QuerySet缓存:在触发过滤器后执行get

时间:2011-05-11 15:44:49

标签: python database django caching django-queryset

将为以下代码执行多少个数据库查询:

q = SomeModel.objects.filter(pk__in=ids)
print q    # The actual query is executed and the result 
           # set evaluated
m = q.get(pk=ids[0])
print m    # Does it reuse the evaluated result set 
           # or does it hit the database the second time?

1 个答案:

答案 0 :(得分:1)

如果您执行以下操作,则懒惰地评估查询集:

q = SomeModel.objects.filter(pk__in=ids)

......立即(即不使用print):

m = q.get(pk=ids[0])

您最终会得到一个SQL查询。它将AND与第二个查询一起>>> import logging >>> l = logging.getLogger('django.db.backends') >>> l.setLevel(logging.DEBUG) >>> l.addHandler(logging.StreamHandler()) 。以这种方式继续添加到查询集是安全的。在Django 1.3中,日志记录已经过修改,您可以在交互式控制台中获得良好的日志记录:

(0.013) SELECT "someapp_somemodel"."id", "someapp_somemodel"."question", "someapp_somemodel"."pub_date" FROM "someapp_somemodel" WHERE ("someapp_somemodel"."id" IN (0, 1) AND "someapp_somemodel"."id" = 0 ); args=(0, 1, 0)

一旦执行实际查询,它将为您提供此类调试信息:

get

请勿在已过滤的查询集上使用filter。如果您想要的模型在您的查询集中,请使用Python表达式(如列表推导或{{1}}等)从您的查询集中获取模型实例,并避免第二次访问数据库(或如果你遍历一个id的列表,那就多次了。