mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	[3.2.x] Changed "Don't overuse count() or exists()" example to Python.
Backport of 8a642b88c3 from master
			
			
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							73e7bfc8f5
						
					
				
				
					commit
					ba71cf38ea
				
			| @@ -260,47 +260,39 @@ Don't overuse ``count()`` and ``exists()`` | |||||||
|  |  | ||||||
| If you are going to need other data from the QuerySet, evaluate it immediately. | 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 | For example, assuming an Email model that has a ``subject`` attribute and a | ||||||
| many-to-many relation to User, the following template code is optimal: | many-to-many relation to User, the following 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 %} |  | ||||||
|  |  | ||||||
|  |     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: | It is optimal because: | ||||||
|  |  | ||||||
| #. Since QuerySets are lazy, this does no database queries if 'display_inbox' | #. Since QuerySets are lazy, this does no database queries if | ||||||
|    is False. |    ``display_emails`` is ``False``. | ||||||
|  |  | ||||||
| #. Use of :ttag:`with` means that we store ``user.emails.all`` in a variable | #. Storing ``user.emails.all()`` in the ``emails`` variable allows its result | ||||||
|    for later use, allowing its cache to be re-used. |    cache to be re-used. | ||||||
|  |  | ||||||
| #. The line ``{% if emails %}`` causes ``QuerySet.__bool__()`` to be called, | #. The line ``if emails`` causes ``QuerySet.__bool__()`` to be called, which | ||||||
|    which causes the ``user.emails.all()`` query to be run on the database, and |    causes the ``user.emails.all()`` query to be run on the database. If there | ||||||
|    at the least the first line to be turned into an ORM object. If there aren't |    aren't any results, it will return ``False``, otherwise ``True``. | ||||||
|    any results, it will return False, otherwise True. |  | ||||||
|  |  | ||||||
| #. The use of ``{{ emails|length }}`` calls ``QuerySet.__len__()``, filling | #. The use of ``len(emails)`` calls ``QuerySet.__len__()``, reusing the result | ||||||
|    out the rest of the cache without doing another query. |    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 | 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 | deliberate optimization performed is using the ``emails`` variable. Using | ||||||
| ``QuerySet.exists()`` or ``QuerySet.count()`` at any point would cause | ``QuerySet.exists()`` for the ``if`` or ``QuerySet.count()`` for the count | ||||||
| additional queries. | would each cause additional queries. | ||||||
|  |  | ||||||
| Use ``QuerySet.update()`` and ``delete()`` | Use ``QuerySet.update()`` and ``delete()`` | ||||||
| ------------------------------------------ | ------------------------------------------ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user