开发者

QuerySet caching: executing get after filter was fired

How many database queries will be executed for the following code:

q = SomeModel.objec开发者_如何转开发ts.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?


Since querysets are evaluated lazily if you do:

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

...immediately folllowed by (i.e., without using print):

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

You'll end up with one SQL query. It'll AND together the first query with the second. It's safe to continue adding to querysets this way. In Django 1.3 the logging is revamped and you can get nice logging in the interactive console:

>>> import logging
>>> l = logging.getLogger('django.db.backends')
>>> l.setLevel(logging.DEBUG)
>>> l.addHandler(logging.StreamHandler())

Which will give you this sort of debugging info as soon as an actual query is executed:

(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)

Don't use get on a filtered queryset. If the model you want is in your queryset, use a Python expression (like a list comprehension or filter or such) to get the model instance out of your queryset, and avoid hitting the database at all a second time (or many more times if you iterate over a list of id's).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜