瀏覽代碼

Changed "Don't overuse count() or exists()" example to Python.

Adam Johnson 4 年之前
父節點
當前提交
8a642b88c3
共有 1 個文件被更改,包括 24 次插入32 次删除
  1. 24 32
      docs/topics/db/optimization.txt

+ 24 - 32
docs/topics/db/optimization.txt

@@ -260,47 +260,39 @@ Don't overuse ``count()`` and ``exists()``
 
 If you are going to need other data from the QuerySet, evaluate it immediately.
 
-For example, assuming an Email model that has a ``body`` attribute and a
-many-to-many relation to User, the following template code is optimal:
-
-.. code-block:: html+django
-
-   {% if display_inbox %}
-     {% with emails=user.emails.all %}
-       {% if emails %}
-         <p>You have {{ emails|length }} email(s)</p>
-         {% for email in emails %}
-           <p>{{ email.body }}</p>
-         {% endfor %}
-       {% else %}
-         <p>No messages today.</p>
-       {% endif %}
-     {% endwith %}
-   {% endif %}
-
+For example, assuming an Email model that has a ``subject`` attribute and a
+many-to-many relation to User, the following code is optimal::
+
+    if display_emails:
+        emails = user.emails.all()
+        if emails:
+            print('You have', len(emails), 'emails:')
+            for email in emails:
+                print(email.subject)
+        else:
+            print('You do not have any emails.')
 
 It is optimal because:
 
-#. Since QuerySets are lazy, this does no database queries if 'display_inbox'
-   is False.
+#. Since QuerySets are lazy, this does no database queries if
+   ``display_emails`` is ``False``.
 
-#. Use of :ttag:`with` means that we store ``user.emails.all`` in a variable
-   for later use, allowing its cache to be re-used.
+#. Storing ``user.emails.all()`` in the ``emails`` variable allows its result
+   cache to be re-used.
 
-#. The line ``{% if emails %}`` causes ``QuerySet.__bool__()`` to be called,
-   which causes the ``user.emails.all()`` query to be run on the database, and
-   at the least the first line to be turned into an ORM object. If there aren't
-   any results, it will return False, otherwise True.
+#. The line ``if emails`` causes ``QuerySet.__bool__()`` to be called, which
+   causes the ``user.emails.all()`` query to be run on the database. If there
+   aren't any results, it will return ``False``, otherwise ``True``.
 
-#. The use of ``{{ emails|length }}`` calls ``QuerySet.__len__()``, filling
-   out the rest of the cache without doing another query.
+#. The use of ``len(emails)`` calls ``QuerySet.__len__()``, reusing the result
+   cache.
 
-#. The :ttag:`for` loop iterates over the already filled cache.
+#. The ``for`` loop iterates over the already filled cache.
 
 In total, this code does either one or zero database queries. The only
-deliberate optimization performed is the use of the :ttag:`with` tag. Using
-``QuerySet.exists()`` or ``QuerySet.count()`` at any point would cause
-additional queries.
+deliberate optimization performed is using the ``emails`` variable. Using
+``QuerySet.exists()`` for the ``if`` or ``QuerySet.count()`` for the count
+would each cause additional queries.
 
 Use ``QuerySet.update()`` and ``delete()``
 ------------------------------------------