如何在django中缓存查询结果?

时间:2010-09-27 14:50:02

标签: python django memcached

我正在尝试在我的django应用上缓存查询结果。但是,似乎它正在缓存整个应用程序。我试过跟随logi:

def cacheView():
  result = cache.get('key')
  if result is None:
    result = Model.objects.get(id=1)
    cache.set('key', 'result')

我在用户登录时调用此方法。但是,如果我在登录后尝试注销,它会让我保持在同一页面,就像我仍然登录一样。我试图在{{3}上关注缓存上的Django文档但是没有成功。

我尝试的另一件事是,如果我尝试在视图上方使用缓存装饰器:

@cache_control(max_age=1000)
def cacheView():
 ...

它确实给出了“未定义响应头”的错误。我是django的新手,确信我错过了一些东西。任何的想法?

2 个答案:

答案 0 :(得分:9)

RTFM :)官方Django文档:Caching and QuerySets

  

每个QuerySet都包含一个缓存,以最大限度地减少数据库访问。 (...)

  

在新创建的QuerySet中,缓存为空。第一次评估QuerySet - 并因此发生数据库查询 - Django将查询结果保存在QuerySet的缓存中并返回已明确请求的结果(例如,如果正在迭代QuerySet,则返回下一个元素)过度)。对QuerySet的后续评估将重用缓存的结果。

在QuerySets(查询结果)的情况下,自动完成缓存。

修改 至于你在问题中粘贴的代码。 如果密钥尚未存在于缓存中,则必须使用add()方法创建密钥,但请记住它将在30秒后默认过期。如果您希望将其保留更长时间,则必须向add()/set()方法添加超时选项。

如果你想缓存你的整个网站(就像你使用它们的装饰者那样),你需要在settings.py中的MIDDLEWARE_CLASSES添加适当的中间件(按照这个确切的顺序,因为中间件顺序很重要,在你定义它们时逐个加载):

MIDDLEWARE_CLASSES = (
    # ...
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',
    # ...
)

如果您没有它们,那么每次使用每站点缓存功能时,您都会收到错误的标头错误。

答案 1 :(得分:1)

从您的示例中不清楚为什么注销会失败,但它不应该与缓存模型有任何关系(除非您缓存User模型并使用缓存用户进行身份验证而不是request.user? )

可以按照你的方式使用cache.get和cache.set(如果不存在则设置将创建一个新密钥)。

缓存查询可能很困难,因为您需要在数据更改时处理缓存失效,以免提供过时的结果。

查看Django的这些查询缓存库,旨在简化操作:

http://jbalogh.me/2010/02/09/cache-machine/

http://packages.python.org/johnny-cache/queryset_cache.html