From fb53981ec80d160d7274622d12c8f036ab469ecb Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 21 Sep 2011 21:02:12 -0400 Subject: [PATCH] No need to extend ImageModel. In fact, ImageModel doesn't exist anymore. Most of IKOptions have also been removed. --- imagekit/fields.py | 48 ++++++++++++++++++++++++++++-------- imagekit/models.py | 59 --------------------------------------------- imagekit/options.py | 27 --------------------- 3 files changed, 38 insertions(+), 96 deletions(-) delete mode 100644 imagekit/models.py diff --git a/imagekit/fields.py b/imagekit/fields.py index 963f4d8..496f919 100755 --- a/imagekit/fields.py +++ b/imagekit/fields.py @@ -3,13 +3,19 @@ import datetime from StringIO import StringIO from imagekit.lib import * from imagekit.utils import img_to_fobj, get_bound_specs +from django.conf import settings from django.core.files.base import ContentFile from django.utils.encoding import force_unicode, smart_str +from django.db import models from django.db.models.signals import post_save, post_delete from django.utils.translation import ugettext_lazy as _ from django.template.loader import render_to_string +# Modify image file buffer size. +ImageFile.MAXBLOCK = getattr(settings, 'PIL_IMAGEFILE_MAXBLOCK', 256 * 2 ** 10) + + class ImageSpec(object): image_field = None @@ -44,10 +50,6 @@ class ImageSpec(object): self.processors = processors self.__dict__.update(kwargs) - def _get_imgfield(self, obj): - field_name = getattr(self, 'image_field', None) or obj._ik.default_image_field - return getattr(obj, field_name) - def process(self, image, obj): fmt = image.format img = image.copy() @@ -111,7 +113,25 @@ class BoundImageSpec(ImageSpec): @property def _imgfield(self): - return self._get_imgfield(self._obj) + field_name = getattr(self, 'image_field', None) + if field_name: + field = getattr(self._obj, field_name) + else: + image_fields = [getattr(self._obj, f.attname) for f in \ + self._obj.__class__._meta.fields if \ + isinstance(f, models.ImageField)] + if len(image_fields) == 0: + raise Exception('{0} does not define any ImageFields, so your ' + '{1} ImageSpec has no image to act on.'.format( + self._obj.__class__.__name__, self.property_name)) + elif len(image_fields) > 1: + raise Exception('{0} defines multiple ImageFields, but you have ' + 'not specified an image_field for your {1} ' + 'ImageSpec.'.format(self._obj.__class__.__name__, + self.property_name)) + else: + field = image_fields[0] + return field def _create(self): if self._imgfield: @@ -156,6 +176,17 @@ class BoundImageSpec(ImageSpec): extension = extensions[0] return extension + def _default_cache_to(self, instance, path, specname, extension): + """Determines the filename to use for the transformed image. Can be + overridden on a per-spec basis by setting the cache_to property on the + spec. + + """ + filepath, basename = os.path.split(path) + filename = os.path.splitext(basename)[0] + new_name = '{0}_{1}.{2}'.format(filename, specname, extension) + return os.path.join(os.path.join('cache', filepath), new_name) + @property def name(self): """ @@ -165,8 +196,7 @@ class BoundImageSpec(ImageSpec): """ filename = self._imgfield.name if filename: - cache_to = self.cache_to or \ - getattr(self._obj._ik, 'default_cache_to', None) + cache_to = self.cache_to or self._default_cache_to if not cache_to: raise Exception('No cache_to or default_cache_to value specified') @@ -183,9 +213,7 @@ class BoundImageSpec(ImageSpec): @property def _storage(self): - return self.storage or \ - getattr(self._obj._ik, 'default_storage', None) or \ - self._imgfield.storage + return self.storage or self._imgfield.storage @property def url(self): diff --git a/imagekit/models.py b/imagekit/models.py deleted file mode 100644 index 56ea545..0000000 --- a/imagekit/models.py +++ /dev/null @@ -1,59 +0,0 @@ -import os -from datetime import datetime -from django.conf import settings -from django.core.files.base import ContentFile -from django.db import models -from django.db.models.base import ModelBase -from django.db.models.signals import post_delete -from django.utils.html import conditional_escape as escape -from django.utils.translation import ugettext_lazy as _ - -from imagekit.fields import ImageSpec -from imagekit.lib import * -from imagekit.options import Options -from imagekit.utils import img_to_fobj, get_bound_specs - -# Modify image file buffer size. -ImageFile.MAXBLOCK = getattr(settings, 'PIL_IMAGEFILE_MAXBLOCK', 256 * 2 ** 10) - - -class ImageModelBase(ModelBase): - """ ImageModel metaclass - - This metaclass parses IKOptions and loads the specified specification - module. - - """ - def __init__(self, name, bases, attrs): - user_opts = getattr(self, 'IKOptions', None) - default_image_field = getattr(user_opts, 'default_image_field', None) - - for k, v in attrs.items(): - if not default_image_field and isinstance(v, models.ImageField): - default_image_field = k - - user_opts.default_image_field = default_image_field - opts = Options(user_opts) - setattr(self, '_ik', opts) - ModelBase.__init__(self, name, bases, attrs) - - -class ImageModel(models.Model): - """ Abstract base class implementing all core ImageKit functionality - - Subclasses of ImageModel are augmented with accessors for each defined - image specification and can override the inner IKOptions class to customize - storage locations and other options. - - """ - __metaclass__ = ImageModelBase - - class Meta: - abstract = True - - class IKOptions: - pass - - @property - def _imgfields(self): - return set([spec._get_imgfield(self) for spec in get_bound_specs(self)]) diff --git a/imagekit/options.py b/imagekit/options.py index 96e4b21..fce55a5 100644 --- a/imagekit/options.py +++ b/imagekit/options.py @@ -8,33 +8,6 @@ class Options(object): """ - default_image_field = None - """The name of the image field property on the model. - Can be overridden on a per-spec basis by setting the image_field property on - the spec. If you don't define default_image_field on your IKOptions class, - it will be automatically populated with the name of the first ImageField the - model defines. - - """ - - default_storage = None - """Storage used for specs that don't define their own storage explicitly. - If neither is specified, the image field's storage will be used. - - """ - - def default_cache_to(self, instance, path, specname, extension): - """Determines the filename to use for the transformed image. Can be - overridden on a per-spec basis by setting the cache_to property on the - spec, or on a per-model basis by defining default_cache_to on your own - IKOptions class. - - """ - filepath, basename = os.path.split(path) - filename = os.path.splitext(basename)[0] - new_name = '{0}_{1}.{2}'.format(filename, specname, extension) - return os.path.join(os.path.join('cache', filepath), new_name) - preprocessor_spec = None save_count_as = None