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).
精彩评论