From 39defa2bd9ca0d1eeffa7ee4f3c7a701db6b385d Mon Sep 17 00:00:00 2001 From: Mitchell Kotler Date: Sat, 19 Nov 2016 12:13:35 -0500 Subject: [PATCH 1/2] Add support for using Django's caching mechanism --- easy_thumbnails/conf.py | 8 ++++++ easy_thumbnails/models.py | 52 +++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/easy_thumbnails/conf.py b/easy_thumbnails/conf.py index 9b61dfa8..7f801a9b 100644 --- a/easy_thumbnails/conf.py +++ b/easy_thumbnails/conf.py @@ -325,6 +325,14 @@ class Settings(AppSettings): still works as a fall back. """ + THUMBNAIL_CACHE = None + """ + Use Django's caching system to cache sources and thumbnails + + Setting this to ``None`` will disable caching. To enable it, set + this to the name of the Django cache you would like to use. + """ + THUMBNAIL_WIDGET_OPTIONS = {'size': (80, 80)} """ Default options for the diff --git a/easy_thumbnails/models.py b/easy_thumbnails/models.py index 4c0d261e..86665437 100644 --- a/easy_thumbnails/models.py +++ b/easy_thumbnails/models.py @@ -6,6 +6,15 @@ from easy_thumbnails import utils, signal_handlers from easy_thumbnails.conf import settings +if settings.THUMBNAIL_CACHE: + try: + from django.core.cache import caches + except ImportError: + from django.core.exceptions import ImproperlyConfigured + raise ImproperlyConfigured( + 'You are trying to use the cache on a version of Django ' + 'that does not support caching') + class FileManager(models.Manager): @@ -13,6 +22,9 @@ def get_file(self, storage, name, create=False, update_modified=None, check_cache_miss=False, **kwargs): kwargs.update(dict(storage_hash=utils.get_storage_hash(storage), name=name)) + if settings.THUMBNAIL_CACHE: + cache = caches[settings.THUMBNAIL_CACHE] + cache_key = self._get_cache_key(kwargs) if create: if update_modified: defaults = kwargs.setdefault('defaults', {}) @@ -21,28 +33,39 @@ def get_file(self, storage, name, create=False, update_modified=None, else: created = False kwargs.pop('defaults', None) - try: - manager = self._get_thumbnail_manager() - obj = manager.get(**kwargs) - except self.model.DoesNotExist: - - if check_cache_miss and storage.exists(name): - # File already in storage, update cache. Using - # get_or_create again in case this was updated while - # storage.exists was running. - obj, created = self.get_or_create(**kwargs) - else: - return + obj = None + if settings.THUMBNAIL_CACHE: + obj = cache.get(cache_key) + if obj is None: + try: + manager = self._get_thumbnail_manager() + obj = manager.get(**kwargs) + except self.model.DoesNotExist: + + if check_cache_miss and storage.exists(name): + # File already in storage, update cache. Using + # get_or_create again in case this was updated while + # storage.exists was running. + obj, created = self.get_or_create(**kwargs) + else: + return if update_modified and not created: if obj.modified != update_modified: - self.filter(pk=obj.pk).update(modified=update_modified) + obj.modified = update_modified + obj.save() + + if settings.THUMBNAIL_CACHE: + cache.set(cache_key, obj, None) return obj def _get_thumbnail_manager(self): return self + def _get_cache_key(self, kwargs): + return 'et:source:{storage_hash}:{name}'.format(**kwargs) + class ThumbnailManager(FileManager): @@ -51,6 +74,9 @@ def _get_thumbnail_manager(self): return self.select_related("dimensions") return self + def _get_cache_key(self, kwargs): + return 'et:thumbnail:{storage_hash}:{name}:{source_id}'.format(**kwargs) + class File(models.Model): storage_hash = models.CharField(max_length=40, db_index=True) From 1554df48813ca2111095f4643294c92d8351dda1 Mon Sep 17 00:00:00 2001 From: Mitchell Kotler Date: Sat, 19 Nov 2016 12:51:16 -0500 Subject: [PATCH 2/2] set source id for cache key correctly --- easy_thumbnails/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easy_thumbnails/models.py b/easy_thumbnails/models.py index 86665437..1fb4f5cf 100644 --- a/easy_thumbnails/models.py +++ b/easy_thumbnails/models.py @@ -75,6 +75,7 @@ def _get_thumbnail_manager(self): return self def _get_cache_key(self, kwargs): + kwargs['source_id'] = kwargs['source'].pk return 'et:thumbnail:{storage_hash}:{name}:{source_id}'.format(**kwargs)