other storages a value of None is set.
The path to the thumbnail relative to MEDIA_ROOT.
+ The thumbnail options as specified in ``EnhancedImageField.thumbnails``
+ and after filling any missing options with the defaults.
If the source image has been saved and thumbnails have been specified,
- instanciate the latter using the ``ThumbnailSpec`` class and add them
- as attributes to the ``EnhancedImageFieldFile`` object.
+ instanciate the latter using the ``ThumbnailSpec`` class. If the
+ thumbnail actually exists on the storage, then add them as attributes
+ to the ``EnhancedImageFieldFile`` object.
+ If a thumbnail does not exist on the storage, it will be generated
+ and set as an ``EnhancedImageFieldFile`` instance attribute whenever
+ it is accessed for the first time.
super(EnhancedImageFieldFile, self).__init__(*args, **kwargs)
If the ``content`` argument is None, then the image data is read
- from the storage. On IOError returns None
+ from the storage. If IOError occurs while trying to read the
+ image data, returns None.
content = ContentFile(self.storage.open(self.name).read())
thumbnail path `%s` and the actual path where the thumbnail \
- print 'generated thumbnail: %s' % path
def __getattr__(self, attrName):
+ """Retrieves an ``EnhancedImageFieldFile`` instance attribute.
+ If a thumbnail attribute is requested, but it has not been set as
+ an ``EnhancedImageFieldFile`` instance attribute, then:
+ 1. Generate the thumbnail
+ 2. Set it as an ``EnhancedImageFieldFile`` instance attribute
+ Here we use the ``EnhancedImageFieldFile`` instance's __dict__ in
+ order to check or set the instance's attributes so as to avoid
+ triggering a recursive call to this function.
+ A good write-up on this exists at: http://bit.ly/c2JL8H
if not self.__dict__.has_key(attrName):
# Proceed in thumbnail generation only if a thumbnail attribute
- print 'requested thumbnail: %s' % attrName
# Generate thumbnail and set the thumbnail specification as
# an attribute to the ``EnhancedImageFieldFile``.
thumb_options = self.field.thumbnails[attrName]
thumb_spec = self.generate_thumbnail(attrName, thumb_options)
self.__dict__[attrName] = thumb_spec
def save(self, name, content, save=True):
"""Saves the source image and generates thumbnails.
source_img_opts = self.field.process_source
thumb_spec = ThumbnailSpec('dummy', source_img_opts, self)
processed_content = process_content_as_image(content, thumb_spec.options)
+ # The following sets the correct filename extension according
name = '%s%s' % (name.rsplit('.', 1), thumb_spec.ext)
- print 'Resized original image'
processed_content = content