def method_cache(seconds=0):
"""
A `seconds` value of `0` means that we will not memcache it.
If a result is cached on instance, return that first. If that fails, check
memcached. If all else fails, hit the db and cache on instance and in memcache.
** NOTE: Methods that return None are always "recached".
"""
from hashlib import sha224
from django.core.cache import cache
def inner_cache(method):
def x(instance, *args, **kwargs):
key = sha224(str(method.__module__) + str(method.__name__) + \
str(instance.id) + str(args) + str(kwargs)).hexdigest()
if hasattr(instance, key):
# has on class cache, return that
result = getattr(instance, key)
else:
result = cache.get(key)
if result is None:
# all caches failed, call the actual method
result = method(instance, *args, **kwargs)
# save to memcache and class attr
if seconds and isinstance(seconds, int):
cache.set(key, result, seconds)
setattr(instance, key, result)
return result
return x
return inner_cache
Comments