Rename ImageSpec to ImageSpecField

The ImageSpec class remains for now, but using it throws
deprecation warnings.
This commit is contained in:
Matthew Tretter 2012-02-11 13:06:48 -05:00
parent c2a4d01b7c
commit c3ef5172c3
5 changed files with 42 additions and 33 deletions

View file

@ -29,11 +29,11 @@ Much like ``django.db.models.ImageField``, Specs are defined as properties
of a model class::
from django.db import models
from imagekit.models import ImageSpec
from imagekit.models import ImageSpecField
class Photo(models.Model):
original_image = models.ImageField(upload_to='photos')
formatted_image = ImageSpec(image_field='original_image', format='JPEG',
formatted_image = ImageSpecField(image_field='original_image', format='JPEG',
options={'quality': 90})
Accessing the spec through a model instance will create the image and return
@ -44,7 +44,7 @@ an ImageFile-like object (just like with a normal
photo.original_image.url # > '/media/photos/birthday.tiff'
photo.formatted_image.url # > '/media/cache/photos/birthday_formatted_image.jpeg'
Check out ``imagekit.models.ImageSpec`` for more information.
Check out ``imagekit.models.ImageSpecField`` for more information.
Processors
@ -55,12 +55,12 @@ something to it, and return the result. By providing a list of processors to
your spec, you can expose different versions of the original image::
from django.db import models
from imagekit.models import ImageSpec
from imagekit.models import ImageSpecField
from imagekit.processors import resize, Adjust
class Photo(models.Model):
original_image = models.ImageField(upload_to='photos')
thumbnail = ImageSpec([Adjust(contrast=1.2, sharpness=1.1),
thumbnail = ImageSpecField([Adjust(contrast=1.2, sharpness=1.1),
resize.Crop(50, 50)], image_field='original_image',
format='JPEG', options={'quality': 90})
@ -87,7 +87,7 @@ implement a ``process()`` method::
class Photo(models.Model):
original_image = models.ImageField(upload_to='photos')
watermarked_image = ImageSpec([Watermark()], image_field='original_image',
watermarked_image = ImageSpecField([Watermark()], image_field='original_image',
format='JPEG', options={'quality': 90})

View file

@ -12,7 +12,7 @@ class AdminThumbnail(object):
def __init__(self, image_field, template=None):
"""
:param image_field: The name of the ImageField or ImageSpec on the
:param image_field: The name of the ImageField or ImageSpecField on the
model to use for the thumbnail.
:param template: The template with which to render the thumbnail

View file

@ -12,9 +12,10 @@ from imagekit.utils import img_to_fobj, get_spec_files, open_image, \
format_to_extension, extension_to_format, UnknownFormatError, \
UnknownExtensionError
from imagekit.processors import ProcessorPipeline, AutoConvert
import warnings
class _ImageSpecMixin(object):
class _ImageSpecFieldMixin(object):
def __init__(self, processors=None, format=None, options={},
autoconvert=True):
self.processors = processors
@ -30,9 +31,9 @@ class _ImageSpecMixin(object):
return processors.process(image.copy())
class ImageSpec(_ImageSpecMixin):
class ImageSpecField(_ImageSpecFieldMixin):
"""
The heart and soul of the ImageKit library, ImageSpec allows you to add
The heart and soul of the ImageKit library, ImageSpecField allows you to add
variants of uploaded images to your models.
"""
@ -44,7 +45,7 @@ class ImageSpec(_ImageSpecMixin):
"""
:param processors: A list of processors to run on the original image.
:param format: The format of the output file. If not provided,
ImageSpec will try to guess the appropriate format based on the
ImageSpecField will try to guess the appropriate format based on the
extension of the filename and the format of the input image.
:param options: A dictionary that will be passed to PIL's
``Image.save()`` method as keyword arguments. Valid options vary
@ -77,7 +78,7 @@ class ImageSpec(_ImageSpecMixin):
"""
_ImageSpecMixin.__init__(self, processors, format=format,
_ImageSpecFieldMixin.__init__(self, processors, format=format,
options=options, autoconvert=autoconvert)
self.image_field = image_field
self.pre_cache = pre_cache
@ -85,7 +86,7 @@ class ImageSpec(_ImageSpecMixin):
self.cache_to = cache_to
def contribute_to_class(self, cls, name):
setattr(cls, name, _ImageSpecDescriptor(self, name))
setattr(cls, name, _ImageSpecFieldDescriptor(self, name))
try:
ik = getattr(cls, '_ik')
except AttributeError:
@ -101,6 +102,13 @@ class ImageSpec(_ImageSpecMixin):
dispatch_uid='%s.delete' % uid)
class ImageSpec(ImageSpecField):
def __init__(self, *args, **kwargs):
warnings.warn('ImageSpec has been renamed to ImageSpecField. Please'
' use that instead.', DeprecationWarning)
super(ImageSpec, self).__init__(*args, **kwargs)
def _get_suggested_extension(name, format):
original_extension = os.path.splitext(name)[1]
try:
@ -124,7 +132,7 @@ def _get_suggested_extension(name, format):
return extension
class _ImageSpecFileMixin(object):
class _ImageSpecFieldFileMixin(object):
def _process_content(self, filename, content):
img = open_image(content)
original_format = img.format
@ -156,7 +164,7 @@ class _ImageSpecFileMixin(object):
return img, content
class ImageSpecFile(_ImageSpecFileMixin, ImageFieldFile):
class ImageSpecFieldFile(_ImageSpecFieldFileMixin, ImageFieldFile):
def __init__(self, instance, field, attname):
ImageFieldFile.__init__(self, instance, field, None)
self.attname = attname
@ -173,12 +181,12 @@ class ImageSpecFile(_ImageSpecFileMixin, ImageFieldFile):
isinstance(f, models.ImageField)]
if len(image_fields) == 0:
raise Exception('%s does not define any ImageFields, so your' \
' %s ImageSpec has no image to act on.' % \
' %s ImageSpecField has no image to act on.' % \
(self.instance.__class__.__name__, self.attname))
elif len(image_fields) > 1:
raise Exception('%s defines multiple ImageFields, but you' \
' have not specified an image_field for your %s' \
' ImageSpec.' % (self.instance.__class__.__name__,
' ImageSpecField.' % (self.instance.__class__.__name__,
self.attname))
else:
field_file = image_fields[0]
@ -275,7 +283,7 @@ class ImageSpecFile(_ImageSpecFileMixin, ImageFieldFile):
def name(self):
"""
Specifies the filename that the cached image will use. The user can
control this by providing a `cache_to` method to the ImageSpec.
control this by providing a `cache_to` method to the ImageSpecField.
"""
name = getattr(self, '_name', None)
@ -303,12 +311,12 @@ class ImageSpecFile(_ImageSpecFileMixin, ImageFieldFile):
def name(self, value):
# TODO: Figure out a better way to handle this. We really don't want
# to allow anybody to set the name, but ``File.__init__`` (which is
# called by ``ImageSpecFile.__init__``) does, so we have to allow it
# at least that one time.
# called by ``ImageSpecFieldFile.__init__``) does, so we have to allow
# it at least that one time.
pass
class _ImageSpecDescriptor(object):
class _ImageSpecFieldDescriptor(object):
def __init__(self, field, attname):
self.attname = attname
self.field = field
@ -317,7 +325,8 @@ class _ImageSpecDescriptor(object):
if instance is None:
return self.field
else:
img_spec_file = ImageSpecFile(instance, self.field, self.attname)
img_spec_file = ImageSpecFieldFile(instance, self.field,
self.attname)
setattr(instance, self.attname, img_spec_file)
return img_spec_file
@ -340,14 +349,14 @@ def _post_delete_handler(sender, instance=None, **kwargs):
spec_file.delete(save=False)
class ProcessedImageFieldFile(ImageFieldFile, _ImageSpecFileMixin):
class ProcessedImageFieldFile(ImageFieldFile, _ImageSpecFieldFileMixin):
def save(self, name, content, save=True):
new_filename = self.field.generate_filename(self.instance, name)
img, content = self._process_content(new_filename, content)
return super(ProcessedImageFieldFile, self).save(name, content, save)
class ProcessedImageField(models.ImageField, _ImageSpecMixin):
class ProcessedImageField(models.ImageField, _ImageSpecFieldMixin):
"""
ProcessedImageField is an ImageField that runs processors on the uploaded
image *before* saving it to storage. This is in contrast to specs, which
@ -365,14 +374,14 @@ class ProcessedImageField(models.ImageField, _ImageSpecMixin):
The ProcessedImageField constructor accepts all of the arguments that
the :class:`django.db.models.ImageField` constructor accepts, as well
as the ``processors``, ``format``, and ``options`` arguments of
:class:`imagekit.models.ImageSpec`.
:class:`imagekit.models.ImageSpecField`.
"""
if 'quality' in kwargs:
raise Exception('The "quality" keyword argument has been'
""" deprecated. Use `options={'quality': %s}` instead.""" \
% kwargs['quality'])
_ImageSpecMixin.__init__(self, processors, format=format,
_ImageSpecFieldMixin.__init__(self, processors, format=format,
options=options, autoconvert=autoconvert)
models.ImageField.__init__(self, verbose_name, name, width_field,
height_field, **kwargs)

View file

@ -186,7 +186,7 @@ class Transpose(object):
class AutoConvert(object):
"""A processor that does some common-sense conversions based on the target
format. This includes things like preserving transparency and quantizing.
This processors is used automatically by ``ImageSpec`` and
This processors is used automatically by ``ImageSpecField`` and
``ProcessedImageField`` immediately before saving the image unless you
specify ``autoconvert=False``.

View file

@ -9,7 +9,7 @@ from django.test import TestCase
from imagekit import utils
from imagekit.lib import Image
from imagekit.models import ImageSpec
from imagekit.models import ImageSpecField
from imagekit.processors import Adjust
from imagekit.processors.resize import Crop
from imagekit.processors.crop import SmartCrop
@ -18,13 +18,13 @@ from imagekit.processors.crop import SmartCrop
class Photo(models.Model):
original_image = models.ImageField(upload_to='photos')
thumbnail = ImageSpec([Adjust(contrast=1.2, sharpness=1.1), Crop(50, 50)],
image_field='original_image', format='JPEG',
thumbnail = ImageSpecField([Adjust(contrast=1.2, sharpness=1.1),
Crop(50, 50)], image_field='original_image', format='JPEG',
options={'quality': 90})
smartcropped_thumbnail = ImageSpec([Adjust(contrast=1.2, sharpness=1.1), SmartCrop(50, 50)],
image_field='original_image', format='JPEG',
options={'quality': 90})
smartcropped_thumbnail = ImageSpecField([Adjust(contrast=1.2,
sharpness=1.1), SmartCrop(50, 50)], image_field='original_image',
format='JPEG', options={'quality': 90})
class IKTest(TestCase):