diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 1042d83..3f1a2f6 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -7,16 +7,18 @@ from ...registry import register class SpecHostField(SpecHost): - def set_spec_id(self, cls, name): + def _set_spec_id(self, cls, name): + spec_id = getattr(self, 'spec_id', None) + # Generate a spec_id to register the spec with. The default spec id is # ":_" - if not getattr(self, 'spec_id', None): + if not spec_id: spec_id = (u'%s:%s:%s' % (cls._meta.app_label, cls._meta.object_name, name)).lower() - # Register the spec with the id. This allows specs to be overridden - # later, from outside of the model definition. - super(SpecHostField, self).set_spec_id(spec_id) + # Register the spec with the id. This allows specs to be overridden + # later, from outside of the model definition. + super(SpecHostField, self).set_spec_id(spec_id) class ImageSpecField(SpecHostField): @@ -59,7 +61,7 @@ class ImageSpecField(SpecHostField): source = image_fields[0] setattr(cls, name, ImageSpecFileDescriptor(self, name, source)) - self.set_spec_id(cls, name) + 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)) @@ -92,7 +94,7 @@ class ProcessedImageField(models.ImageField, SpecHostField): height_field, **kwargs) def contribute_to_class(self, cls, name): - self.set_spec_id(cls, name) + self._set_spec_id(cls, name) return super(ProcessedImageField, self).contribute_to_class(cls, name) diff --git a/imagekit/registry.py b/imagekit/registry.py index a28738f..620f9f8 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -15,7 +15,8 @@ class GeneratorRegistry(object): before_access.connect(self.before_access_receiver) def register(self, id, generator): - if id in self._generators: + registered_generator = self._generators.get(id) + if registered_generator and generator != self._generators[id]: raise AlreadyRegistered('The generator with id %s is' ' already registered' % id) self._generators[id] = generator diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index c12acfa..9a2ba66 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -4,7 +4,7 @@ from hashlib import md5 import pickle from ..cachefiles.backends import get_default_cachefile_backend from ..cachefiles.strategies import StrategyWrapper -from ..exceptions import MissingSource +from ..exceptions import AlreadyRegistered, MissingSource from ..processors import ProcessorPipeline from ..utils import open_image, img_to_fobj, get_by_qname from ..registry import generator_registry, register @@ -202,7 +202,17 @@ class SpecHost(object): """ self.spec_id = id - register.generator(id, self._original_spec) + + if self._original_spec: + try: + register.generator(id, self._original_spec) + except AlreadyRegistered: + # Fields should not cause AlreadyRegistered exceptions. If a + # spec is already registered, that should be used. It is + # especially important that an error is not thrown here because + # of South, which will create duplicate models as part of its + # "fake orm," therefore re-registering specs. + pass def get_spec(self, source): """