I have a memoized Django model manager method as follows:
class GroupManager(models.Manager):
def get_for_user(self, user):
cache_key = 'groups_%s' % (user.id)
if not hasattr(self, key):
groups = get_groups_somehow()
setattr(self, cache_key, groups)
return getattr(self, cache_key)
But the memoized value persists beyond the request / response cycle; i.e. the value is not re-calculated in the subsequent requests until the server is restarted. This must be because the manager instance is not destroyed.
So, how can I properly memoize model manager methods?
with inspiration from https://stackoverflow.com/a/1526245/287923, but simplifying it, i've implemented a request cache as follows:
from threading import currentThread
caches = {}
class RequestCache(object):
def set(self, key, value):
cache_id = hash(currentThread())
if caches.get(cache_id):
caches[cache_id][key] = value
else:
caches[cache_id] = {key: value}
def get(self, key):
cache_id = hash(currentThread())
cache = caches.get(cache_id)
if cache:
return cache.get(key)
return None
class RequestCacheMiddleware(object):
def process_response(self, request, response):
cache_id = hash(currentThread())
if caches.get(cache_id):
del(caches[cache_id])
return response
caches
is a dictionary of cache dictionaries, accessed via get
& set
methods. a middleware clears the cache for the current thread in process_response
method, after the response is rendered.
it is used like this:
from request_cache import RequestCache
cache = RequestCache()
cache.get(key)
cache.set(key, value)