django-imagekit/imagekit/models.py
Eric Eldredge b1c5432310 Implemented post_save and post_delete handlers for ImageSpecs.
Removed the save and clear_cache methods from ImageModel (along with helpers).
Now, whenever an ImageSpec is contributed to a model, handlers are created for
the post_save and post_delete signals. The post_save handler does the work of
running the ImageSpec processors and caching the resulting file, while the
post_delete handler does the work cleaning up the cached files.
2011-09-21 09:56:27 -04:00

77 lines
2.2 KiB
Python

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.specs import ImageSpec
from imagekit.lib import *
from imagekit.options import Options
from imagekit.utils import img_to_fobj
# Modify image file buffer size.
ImageFile.MAXBLOCK = getattr(settings, 'PIL_IMAGEFILE_MAXBLOCK', 256 * 2 ** 10)
# Choice tuples for specifying the crop origin.
# These are provided for convenience.
CROP_HORZ_CHOICES = (
(0, _('left')),
(1, _('center')),
(2, _('right')),
)
CROP_VERT_CHOICES = (
(0, _('top')),
(1, _('center')),
(2, _('bottom')),
)
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)
specs = []
default_image_field = getattr(user_opts, 'default_image_field', None)
for k, v in attrs.items():
if isinstance(v, ImageSpec):
specs.append(v)
elif not default_image_field and isinstance(v, models.ImageField):
default_image_field = k
user_opts.specs = specs
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 self._ik.specs])