【问题标题】:django: how to memoize model manager methods?django:如何记忆模型管理器方法?
【发布时间】:2012-05-17 23:11:58
【问题描述】:
我有一个记忆的 Django 模型管理器方法如下:
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)
但是记忆值在请求/响应周期之外仍然存在;即在服务器重新启动之前,不会在后续请求中重新计算该值。这一定是因为管理器实例没有被销毁。
那么,如何正确记忆模型管理器方法?
【问题讨论】:
标签:
python
django
memoization
django-managers
【解决方案1】:
不会重新计算键值,因为您告诉它一旦键存在就不会重新计算。如果您想在后续调用中重新计算它,请重新排序您的代码
class GroupManager(models.Manager):
def get_for_user(self, user):
cache_key = 'groups_%s' % (user.id)
groups = get_groups_somehow()
setattr(self, cache_key, groups)
return getattr(self, cache_key)
如果您想在不重新计算的情况下获取缓存值,只需使用 getattr 和经理上的正确键即可。
【解决方案2】:
受https://stackoverflow.com/a/1526245/287923 的启发,但为了简化它,我实现了一个请求缓存,如下所示:
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 是缓存字典的字典,通过get 和set 方法访问。在呈现响应后,中间件会在 process_response 方法中清除当前线程的缓存。
它是这样使用的:
from request_cache import RequestCache
cache = RequestCache()
cache.get(key)
cache.set(key, value)