0

Django 在他们的文档中声明所有查询集都会自动缓存,https://docs.djangoproject.com/en/dev/topics/db/queries/#caching-and-querysets。但他们对这个功能的细节并不是特别具体。

他们给出的示例是将 qs 保存在 python 变量中,第一个之后的后续调用将从缓存中获取。

queryset = Entry.objects.all()
print([p.headline for p in queryset]) # 评估查询集。
print([p.pub_date for p in queryset]) # 重用评估中的缓存。

因此,即使在用户加载视图时随后在没有变量的情况下进行了两次精确的查询集调用,结果是否不会被缓存?

# When the user loads the homepage, call number one (not cached)
def home(request):    
    entries = Entry.objects.filter(something)
    return render_to_response(...)

# Call number two, is this cached automatically? Or do I need to import cache and
# manually do it? This is the same method as above, called twice
def home(request):    
    entries = Entry.objects.filter(something)
    return render_to_response(...)

抱歉,如果这令人困惑,我将方法粘贴了两次,以使用户看起来像是两次调用它,它只是一种方法。条目是否自动缓存?

谢谢

4

3 回答 3

1

它没有被缓存有两个原因:

  • 当您使用 justfilter但不“循环”结果时,尚未评估查询集,这意味着缓存仍然是空的。
  • 即使它们会被评估,它也不会被缓存,因为当您第二次调用该函数时,查询集被重新创建(新的局部变量),即使您在第一次调用该函数时就已经创建了它。第二个函数调用根本不“知道”你之前做了什么。它只是一个新的查询集实例。在这种情况下,您可能会依赖数据库缓存。
于 2012-09-27T07:11:02.693 回答
1

您给出的queryset示例正确地表明它们querysets是懒惰的,即第一次使用它们。因此,当随后再次使用时,它们在分配给变量时不会在同一流程中进行评估。这并不完全是缓存,而是重新使用评估的表达式,只要它以优化的方式可用。

对于您正在查看的缓存类型,即两次调用相同的视图,您需要在第一次获取数据库对象时手动缓存它。Memcached对此很有用。然后随后检查并获取,如下例所示。

def view(request):
    results = cache.get(request.user.id)
    if not results:
        results = do_a_ton_of_work()
        cache.set(request.user.id, results)

当然,从代理服务器到每个 url 缓存,还有很多其他方法可以在不同级别进行缓存。什么最适合你。是关于这个主题的好读物。

于 2012-09-27T07:15:48.693 回答
0

Memcached 是内置模块,它工作得很好,但即使你可以尝试“johnny cache”以获得更好的结果。

你可以在这里获得更多信息

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

于 2012-09-27T07:58:40.610 回答