mirror of
https://github.com/Hopiu/django-imagekit.git
synced 2026-03-17 05:40:25 +00:00
Merge branch 'fix-234' into develop
This commit is contained in:
commit
f684b4e4e0
2 changed files with 36 additions and 7 deletions
|
|
@ -1,3 +1,4 @@
|
|||
from copy import copy
|
||||
from django.conf import settings
|
||||
from django.db.models.fields.files import ImageFieldFile
|
||||
from ..cachefiles.backends import get_default_cachefile_backend
|
||||
|
|
@ -93,25 +94,41 @@ class ImageSpec(BaseImageSpec):
|
|||
fn = get_by_qname(settings.IMAGEKIT_SPEC_CACHEFILE_NAMER, 'namer')
|
||||
return fn(self)
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
src = getattr(self, '_source', None)
|
||||
if not src:
|
||||
field_data = getattr(self, '_field_data', None)
|
||||
if field_data:
|
||||
src = self._source = getattr(field_data['instance'], field_data['attname'])
|
||||
del self._field_data
|
||||
return src
|
||||
|
||||
@source.setter
|
||||
def source(self, value):
|
||||
self._source = value
|
||||
|
||||
def __getstate__(self):
|
||||
state = self.__dict__
|
||||
state = copy(self.__dict__)
|
||||
|
||||
# Unpickled ImageFieldFiles won't work (they're missing a storage
|
||||
# object). Since they're such a common use case, we special case them.
|
||||
# Unfortunately, this also requires us to add the source getter to
|
||||
# lazily retrieve the source on the reconstructed object; simply trying
|
||||
# to look up the source in ``__setstate__`` would require us to get the
|
||||
# model instance but, if ``__setstate__`` was called as part of
|
||||
# deserializing that model, the model wouldn't be fully reconstructed
|
||||
# yet, preventing us from accessing the source field.
|
||||
# (This is issue #234.)
|
||||
if isinstance(self.source, ImageFieldFile):
|
||||
field = getattr(self.source, 'field')
|
||||
state['_field_data'] = {
|
||||
'instance': getattr(self.source, 'instance', None),
|
||||
'attname': getattr(field, 'name', None),
|
||||
}
|
||||
state.pop('_source', None)
|
||||
return state
|
||||
|
||||
def __setstate__(self, state):
|
||||
field_data = state.pop('_field_data', None)
|
||||
self.__dict__ = state
|
||||
if field_data:
|
||||
self.source = getattr(field_data['instance'], field_data['attname'])
|
||||
|
||||
def get_hash(self):
|
||||
return hashers.pickle([
|
||||
self.source.name,
|
||||
|
|
|
|||
|
|
@ -11,3 +11,15 @@ def test_imagespecfield():
|
|||
instance = create_photo('pickletest2.jpg')
|
||||
thumbnail = pickleback(instance.thumbnail)
|
||||
thumbnail.generate()
|
||||
|
||||
|
||||
def test_circular_ref():
|
||||
"""
|
||||
A model instance with a spec field in its dict shouldn't raise a KeyError.
|
||||
|
||||
This corresponds to #234
|
||||
|
||||
"""
|
||||
instance = create_photo('pickletest3.jpg')
|
||||
instance.thumbnail # Cause thumbnail to be added to instance's __dict__
|
||||
pickleback(instance)
|
||||
|
|
|
|||
Loading…
Reference in a new issue