Commit 8365d76d authored by Tim Graham's avatar Tim Graham
Browse files

Fixed #20513 - Expanded docs on QuerySet caching.

Thanks seddonym.
parent 33dd8f54
Loading
Loading
Loading
Loading
+40 −3
Original line number Diff line number Diff line
@@ -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 <limiting-querysets>` 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