From 8365d76da01af1d4391cba32d62178791d074b06 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 28 May 2013 08:41:13 -0400 Subject: [PATCH] Fixed #20513 - Expanded docs on QuerySet caching. Thanks seddonym. --- docs/topics/db/queries.txt | 43 +++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt index 39ef2b33fd..bdbdd3fa2a 100644 --- a/docs/topics/db/queries.txt +++ b/docs/topics/db/queries.txt @@ -714,9 +714,9 @@ for you transparently. Caching and QuerySets --------------------- -Each :class:`~django.db.models.query.QuerySet` contains a cache, to minimize -database access. It's important to understand how it works, in order to write -the most efficient code. +Each :class:`~django.db.models.query.QuerySet` contains a cache to minimize +database access. Understanding how it works will allow you to write the most +efficient code. In a newly created :class:`~django.db.models.query.QuerySet`, the cache is empty. The first time a :class:`~django.db.models.query.QuerySet` is evaluated @@ -747,6 +747,43 @@ To avoid this problem, simply save the >>> print([p.headline for p in queryset]) # Evaluate the query set. >>> print([p.pub_date for p in queryset]) # Re-use the cache from the evaluation. +When querysets are not cached +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Querysets do not always cache their results. When evaluating only *part* of +the queryset, the cache is checked, but if it is not populated then the items +returned by the subsequent query are not cached. Specifically, this means that +:ref:`limiting the queryset ` using an array slice or an +index will not populate the cache. + +For example, repeatedly getting a certain index in a queryset object will query +the database each time:: + + >>> queryset = Entry.objects.all() + >>> print queryset[5] # Queries the database + >>> print queryset[5] # Queries the database again + +However, if the entire queryset has already been evaluated, the cache will be +checked instead:: + + >>> queryset = Entry.objects.all() + >>> [entry for entry in queryset] # Queries the database + >>> print queryset[5] # Uses cache + >>> print queryset[5] # Uses cache + +Here are some examples of other actions that will result in the entire queryset +being evaluated and therefore populate the cache:: + + >>> [entry for entry in queryset] + >>> bool(queryset) + >>> entry in queryset + >>> list(queryset) + +.. note:: + + Simply printing the queryset will not populate the cache. This is because + the call to ``__repr__()`` only returns a slice of the entire queryset. + .. _complex-lookups-with-q: Complex lookups with Q objects