diff --git a/docs/caching.rst b/docs/caching.rst index 4e2b8a9..8264089 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -185,6 +185,11 @@ Or, in Python: def on_source_saved(self, file): file.generate() +.. note:: + + If you use custom storage backend for some specs, + (storage passed to the field different than configured one) + it's required the storage to be pickleable __ https://pypi.python.org/pypi/django-celery diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 594df57..08ea04b 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -144,8 +144,24 @@ class ImageCacheFile(BaseIKFile, ImageFile): # file is hidden link to "file" attribute state.pop('_file', None) + # remove storage from state as some non-FileSystemStorage can't be + # pickled + settings_storage = get_singleton( + settings.IMAGEKIT_DEFAULT_FILE_STORAGE, + 'file storage backend' + ) + if state['storage'] == settings_storage: + state.pop('storage') return state + def __setstate__(self, state): + if 'storage' not in state: + state['storage'] = get_singleton( + settings.IMAGEKIT_DEFAULT_FILE_STORAGE, + 'file storage backend' + ) + self.__dict__.update(state) + def __nonzero__(self): # Python 2 compatibility return self.__bool__() diff --git a/tests/test_serialization.py b/tests/test_serialization.py index b995658..10dd550 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -37,4 +37,7 @@ def test_cachefiles(): # remove link to file from spec source generator # test __getstate__ of ImageCacheFile file.generator.source = None - pickleback(file) + restored_file = pickleback(file) + assert file is not restored_file + # Assertion for #437 and #451 + assert file.storage is restored_file.storage