Skip to content

Instantly share code, notes, and snippets.

@dnozay
Created January 8, 2015 08:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dnozay/2888ac383b41d0a45f4d to your computer and use it in GitHub Desktop.
Save dnozay/2888ac383b41d0a45f4d to your computer and use it in GitHub Desktop.
django-rest-framework mixin that caches serialization output with cache key based on DateTimeField(auto_now=True)
# License: MIT
# django-rest-framework mixin
class CachedReprMixin(serializers.ModelSerializer):
'''
mixin for ModelSerializer subclass whose model has a 'modified' field.
assuming the model has a 'modified' field:
modified = models.DateTimeField(auto_now=True)
the core assumption is that if there is a change to the object, the value
of 'modified' will be different. which makes it very interesting for
creating a cache key.
'''
def to_representation(self, obj):
'''
custom function to deal with obj representation.
we are trying to cut down number of queries, so use cache
where possible.
'''
# only handle single objects
if not isinstance(obj, list):
# we want to distinguish based on:
# 1. serializer (different serializer = different fields)
# 2. model and pk (different object = different key)
# 3. modified field (different dates = different fields)
key = '{0.__class__.__name__}:{1.__class__.__name__}:{1.pk}:{2}'
try:
obj_key = key.format(self, obj, obj.modified.strftime('%s'))
data = CACHE.get(obj_key, None)
if data is None:
LOG.info('cache miss: %s', obj_key)
data = super(CachedReprMixin, self).to_representation(obj)
CACHE.set(obj_key, json.dumps(data), timeout=None)
else:
LOG.info('cache hit: %s', obj_key)
data = json.loads(data)
return data
except AttributeError:
# don't have a modified field.
pass
# default serialization if cannot use the cache.
return super(CachedReprMixin, self).to_representation(obj)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment