diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index e2ccf26..61a7dd3 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,6 +1,8 @@ from __future__ import unicode_literals from django.db import models +from django.db.models.signals import class_prepared +from django.dispatch import receiver from .files import ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor from ...specs import SpecHost @@ -46,27 +48,38 @@ class ImageSpecField(SpecHostField): def contribute_to_class(self, cls, name): # If the source field name isn't defined, figure it out. - source = self.source - if not source: - image_fields = [f.attname for f in cls._meta.fields if - isinstance(f, models.ImageField)] - if len(image_fields) == 0: - raise Exception( - '%s does not define any ImageFields, so your %s' - ' ImageSpecField has no image to act on.' % - (cls.__name__, name)) - elif len(image_fields) > 1: - raise Exception( - '%s defines multiple ImageFields, but you have not' - ' specified a source for your %s ImageSpecField.' % - (cls.__name__, name)) - source = image_fields[0] - setattr(cls, name, ImageSpecFileDescriptor(self, name, source)) - self._set_spec_id(cls, name) + def register_source_group(source): + setattr(cls, name, ImageSpecFileDescriptor(self, name, source)) + self._set_spec_id(cls, name) + + # Add the model and field as a source for this spec id + register.source_group(self.spec_id, ImageFieldSourceGroup(cls, source)) + + if self.source: + register_source_group(self.source) + else: + # The source argument is not defined + # Then we need to see if there is only one ImageField in that model + # But we need to do that after full model initialization + + @receiver(class_prepared, sender=cls, weak=False) + def handle_model_preparation(sender, **kwargs): + + image_fields = [f.attname for f in cls._meta.fields if + isinstance(f, models.ImageField)] + if len(image_fields) == 0: + raise Exception( + '%s does not define any ImageFields, so your %s' + ' ImageSpecField has no image to act on.' % + (cls.__name__, name)) + elif len(image_fields) > 1: + raise Exception( + '%s defines multiple ImageFields, but you have not' + ' specified a source for your %s ImageSpecField.' % + (cls.__name__, name)) + register_source_group(image_fields[0]) - # Add the model and field as a source for this spec id - register.source_group(self.spec_id, ImageFieldSourceGroup(cls, source)) class ProcessedImageField(models.ImageField, SpecHostField):