Improve logic of contributing ImageSpecFields to Models

- If `source` is defined then register source group immediately
- If `source` is not defined then create a signal handler and attach it to
`class_prepared` signal which will see if there is only one ImageField in
the given model.

This will fix problems coused in Python 3 about using ImageSpecField
without providing a `source`.
This commit is contained in:
Venelin Stoykov 2013-12-15 02:34:25 +02:00 committed by Venelin Stoykov
parent 8a600d30b3
commit 26aa19eeef

View file

@ -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):