Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting to use Django's cache #430

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions easy_thumbnails/conf.py
Expand Up @@ -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
Expand Down
53 changes: 40 additions & 13 deletions easy_thumbnails/models.py
Expand Up @@ -6,13 +6,25 @@
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):

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', {})
Expand All @@ -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):

Expand All @@ -51,6 +74,10 @@ def _get_thumbnail_manager(self):
return self.select_related("dimensions")
return self

def _get_cache_key(self, kwargs):
kwargs['source_id'] = kwargs['source'].pk
return 'et:thumbnail:{storage_hash}:{name}:{source_id}'.format(**kwargs)


class File(models.Model):
storage_hash = models.CharField(max_length=40, db_index=True)
Expand Down