mirror of
				https://github.com/django/django.git
				synced 2025-10-30 00:56:09 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			161 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| =====================
 | |
| Query-related classes
 | |
| =====================
 | |
| 
 | |
| .. currentmodule:: django.db.models
 | |
| 
 | |
| This document provides reference material for query-related tools not
 | |
| documented elsewhere.
 | |
| 
 | |
| ``F()`` expressions
 | |
| ===================
 | |
| 
 | |
| .. class:: F
 | |
| 
 | |
| An ``F()`` object represents the value of a model field. It makes it possible
 | |
| to refer to model field values and perform database operations using them
 | |
| without actually having to pull them out of the database into Python memory.
 | |
| 
 | |
| Instead, Django uses the ``F()`` object to generate a SQL expression that
 | |
| describes the required operation at the database level.
 | |
| 
 | |
| This is easiest to understand through an example. Normally, one might do
 | |
| something like this::
 | |
| 
 | |
|     # Tintin filed a news story!
 | |
|     reporter = Reporters.objects.get(name='Tintin')
 | |
|     reporter.stories_filed += 1
 | |
|     reporter.save()
 | |
| 
 | |
| Here, we have pulled the value of ``reporter.stories_filed`` from the database
 | |
| into memory and manipulated it using familiar Python operators, and then saved
 | |
| the object back to the database. But instead we could also have done::
 | |
| 
 | |
|     from django.db.models import F
 | |
|     reporter = Reporters.objects.get(name='Tintin')
 | |
|     reporter.stories_filed = F('stories_filed') + 1
 | |
|     reporter.save()
 | |
| 
 | |
| Although ``reporter.stories_filed = F('stories_filed') + 1`` looks like a
 | |
| normal Python assignment of value to an instance attribute, in fact it's an SQL
 | |
| construct describing an operation on the database.
 | |
| 
 | |
| When Django encounters an instance of ``F()``, it overrides the standard Python
 | |
| operators to create an encapsulated SQL expression; in this case, one which
 | |
| instructs the database to increment the database field represented by
 | |
| ``reporter.stories_filed``.
 | |
| 
 | |
| Whatever value is or was on ``reporter.stories_filed``, Python never gets to
 | |
| know about it - it is dealt with entirely by the database. All Python does,
 | |
| through Django's ``F()`` class, is create the SQL syntax to refer to the field
 | |
| and describe the operation.
 | |
| 
 | |
| .. note::
 | |
| 
 | |
|    In order to access the new value that has been saved in this way, the object
 | |
|    will need to be reloaded::
 | |
| 
 | |
|        reporter = Reporters.objects.get(pk=reporter.pk)
 | |
| 
 | |
| As well as being used in operations on single instances as above, ``F()`` can
 | |
| be used on ``QuerySets`` of object instances, with ``update()``. This reduces
 | |
| the two queries we were using above - the ``get()`` and the
 | |
| :meth:`~Model.save()` - to just one::
 | |
| 
 | |
|     reporter = Reporters.objects.filter(name='Tintin')
 | |
|     reporter.update(stories_filed=F('stories_filed') + 1)
 | |
| 
 | |
| We can also use :meth:`~django.db.models.query.QuerySet.update()` to increment
 | |
| the field value on multiple objects - which could be very much faster than
 | |
| pulling them all into Python from the database, looping over them, incrementing
 | |
| the field value of each one, and saving each one back to the database::
 | |
| 
 | |
|     Reporter.objects.all().update(stories_filed=F('stories_filed') + 1)
 | |
| 
 | |
| ``F()`` therefore can offer performance advantages by:
 | |
| 
 | |
| * getting the database, rather than Python, to do work
 | |
| * reducing the number of queries some operations require
 | |
| 
 | |
| .. _avoiding-race-conditions-using-f:
 | |
| 
 | |
| Avoiding race conditions using ``F()``
 | |
| --------------------------------------
 | |
| 
 | |
| Another useful benefit of ``F()`` is that having the database - rather than
 | |
| Python - update a field's value avoids a *race condition*.
 | |
| 
 | |
| If two Python threads execute the code in the first example above, one thread
 | |
| could retrieve, increment, and save a field's value after the other has
 | |
| retrieved it from the database. The value that the second thread saves will be
 | |
| based on the original value; the work of the first thread will simply be lost.
 | |
| 
 | |
| If the database is responsible for updating the field, the process is more
 | |
| robust: it will only ever update the field based on the value of the field in
 | |
| the database when the :meth:`~Model.save()` or ``update()`` is executed, rather
 | |
| than based on its value when the instance was retrieved.
 | |
| 
 | |
| Using ``F()`` in filters
 | |
| ------------------------
 | |
| 
 | |
| ``F()`` is also very useful in ``QuerySet`` filters, where they make it
 | |
| possible to filter a set of objects against criteria based on their field
 | |
| values, rather than on Python values.
 | |
| 
 | |
| This is documented in :ref:`using F() expressions in queries
 | |
| <using-f-expressions-in-filters>`
 | |
| 
 | |
| Supported operations with ``F()``
 | |
| ---------------------------------
 | |
| 
 | |
| As well as addition, Django supports subtraction, multiplication, division,
 | |
| and modulo arithmetic with ``F()`` objects, using Python constants,
 | |
| variables, and even other ``F()`` objects.
 | |
| 
 | |
| .. versionadded:: 1.7
 | |
| 
 | |
|     The power operator ``**`` is also supported.
 | |
| 
 | |
| ``Q()`` objects
 | |
| ===============
 | |
| 
 | |
| .. class:: Q
 | |
| 
 | |
| A ``Q()`` object, like an :class:`~django.db.models.F` object, encapsulates a
 | |
| SQL expression in a Python object that can be used in database-related
 | |
| operations.
 | |
| 
 | |
| In general, ``Q() objects`` make it possible to define and reuse conditions.
 | |
| This permits the :ref:`construction of complex database queries
 | |
| <complex-lookups-with-q>` using ``|`` (``OR``) and ``&`` (``AND``) operators;
 | |
| in particular, it is not otherwise possible to use ``OR`` in ``QuerySets``.
 | |
| 
 | |
| ``Prefetch()`` objects
 | |
| ======================
 | |
| 
 | |
| .. versionadded:: 1.7
 | |
| 
 | |
| .. class:: Prefetch(lookup, queryset=None, to_attr=None)
 | |
| 
 | |
| The ``Prefetch()`` object can be used to control the operation of
 | |
| :meth:`~django.db.models.query.QuerySet.prefetch_related()`.
 | |
| 
 | |
| The ``lookup`` argument describes the relations to follow and works the same
 | |
| as the string based lookups passed to
 | |
| :meth:`~django.db.models.query.QuerySet.prefetch_related()`.
 | |
| 
 | |
| The ``queryset`` argument supplies a base ``QuerySet`` for the given lookup.
 | |
| This is useful to further filter down the prefetch operation, or to call
 | |
| :meth:`~django.db.models.query.QuerySet.select_related()` from the prefetched
 | |
| relation, hence reducing the number of queries even further.
 | |
| 
 | |
| The ``to_attr`` argument sets the result of the prefetch operation to a custom
 | |
| attribute.
 | |
| 
 | |
| .. note::
 | |
| 
 | |
|     When using ``to_attr`` the prefetched result is stored in a list.
 | |
|     This can provide a significant speed improvement over traditional
 | |
|     ``prefetch_related`` calls which store the cached result within a
 | |
|     ``QuerySet`` instance.
 |