summaryrefslogtreecommitdiff
path: root/docs/ref
diff options
context:
space:
mode:
authorAdam Johnson <me@adamj.eu>2023-11-29 09:35:34 +0000
committerJacob Walls <jacobtylerwalls@gmail.com>2025-10-16 14:52:22 -0400
commite097e8a12f21a4e92594830f1ad1942b31916d0f (patch)
tree43f448bf968f0c6c1a48577cbc4d1ba5b920624a /docs/ref
parentf6bd90c84050a1c74fe2161cced00e7282cb845c (diff)
Fixed #28586 -- Added model field fetch modes.
May your database queries be much reduced with minimal effort. co-authored-by: Andreas Pelme <andreas@pelme.se> co-authored-by: Simon Charette <charette.s@gmail.com> co-authored-by: Jacob Walls <jacobtylerwalls@gmail.com>
Diffstat (limited to 'docs/ref')
-rw-r--r--docs/ref/exceptions.txt10
-rw-r--r--docs/ref/models/instances.txt8
-rw-r--r--docs/ref/models/querysets.txt60
3 files changed, 51 insertions, 27 deletions
diff --git a/docs/ref/exceptions.txt b/docs/ref/exceptions.txt
index bbd959e95d..93c6ec4203 100644
--- a/docs/ref/exceptions.txt
+++ b/docs/ref/exceptions.txt
@@ -165,6 +165,16 @@ Django core exception classes are defined in ``django.core.exceptions``.
- A field name is invalid
- A query contains invalid order_by arguments
+``FieldFetchBlocked``
+---------------------
+
+.. versionadded:: 6.1
+
+.. exception:: FieldFetchBlocked
+
+ Raised when a field would be fetched on-demand and the
+ :attr:`~django.db.models.RAISE` fetch mode is active.
+
``ValidationError``
-------------------
diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt
index c8cf5957ba..2ce8dc4a36 100644
--- a/docs/ref/models/instances.txt
+++ b/docs/ref/models/instances.txt
@@ -180,10 +180,10 @@ update, you could write a test similar to this::
obj.refresh_from_db()
self.assertEqual(obj.val, 2)
-Note that when deferred fields are accessed, the loading of the deferred
-field's value happens through this method. Thus it is possible to customize
-the way deferred loading happens. The example below shows how one can reload
-all of the instance's fields when a deferred field is reloaded::
+When a deferred field is loaded on-demand for a single model instance, the
+loading happens through this method. Thus it is possible to customize the way
+this loading happens. The example below shows how one can reload all of the
+instance's fields when a deferred field is loaded on-demand::
class ExampleModel(models.Model):
def refresh_from_db(self, using=None, fields=None, **kwargs):
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index f290970d2c..3840a2f97e 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -1022,15 +1022,38 @@ Uses SQL's ``EXCEPT`` operator to keep only elements present in the
See :meth:`union` for some restrictions.
+``fetch_mode()``
+~~~~~~~~~~~~~~~~
+
+.. versionadded:: 6.1
+
+.. method:: fetch_mode(mode)
+
+Returns a ``QuerySet`` that sets the given fetch mode for all model instances
+created by this ``QuerySet``. The fetch mode controls on-demand loading of
+fields when they are accessed, such as for foreign keys and deferred fields.
+For example, to use the :attr:`~django.db.models.FETCH_PEERS` mode to
+batch-load all related objects on first access:
+
+.. code-block:: python
+
+ from django.db import models
+
+ books = Book.objects.fetch_mode(models.FETCH_PEERS)
+
+See more in the :doc:`fetch mode topic guide </topics/db/fetch-modes>`.
+
``select_related()``
~~~~~~~~~~~~~~~~~~~~
.. method:: select_related(*fields)
-Returns a ``QuerySet`` that will "follow" foreign-key relationships, selecting
-additional related-object data when it executes its query. This is a
-performance booster which results in a single more complex query but means
-later use of foreign-key relationships won't require database queries.
+Returns a ``QuerySet`` that will join in the named foreign-key relationships,
+selecting additional related objects when it executes its query. This method
+can be a performance booster, fetching data ahead of time rather than
+triggering on-demand loading through the model instances'
+:doc:`fetch mode </topics/db/fetch-modes>`, at the cost of a more complex
+initial query.
The following examples illustrate the difference between plain lookups and
``select_related()`` lookups. Here's standard lookup::
@@ -1050,20 +1073,8 @@ And here's ``select_related`` lookup::
# in the previous query.
b = e.blog
-You can use ``select_related()`` with any queryset of objects::
-
- from django.utils import timezone
-
- # Find all the blogs with entries scheduled to be published in the future.
- blogs = set()
-
- for e in Entry.objects.filter(pub_date__gt=timezone.now()).select_related("blog"):
- # Without select_related(), this would make a database query for each
- # loop iteration in order to fetch the related blog for each entry.
- blogs.add(e.blog)
-
-The order of ``filter()`` and ``select_related()`` chaining isn't important.
-These querysets are equivalent::
+You can use ``select_related()`` with any queryset. The order of chaining with
+other methods isn't important. For example, these querysets are equivalent::
Entry.objects.filter(pub_date__gt=timezone.now()).select_related("blog")
Entry.objects.select_related("blog").filter(pub_date__gt=timezone.now())
@@ -1141,12 +1152,15 @@ that is that ``select_related('foo', 'bar')`` is equivalent to
.. method:: prefetch_related(*lookups)
-Returns a ``QuerySet`` that will automatically retrieve, in a single batch,
-related objects for each of the specified lookups.
+Returns a ``QuerySet`` that will automatically retrieve the given lookups, each
+in one extra batch query. Prefetching is a way to optimize database access
+when you know you'll be accessing related objects later, so you can avoid
+triggering the on-demand loading behavior of the model instances'
+:doc:`fetch mode </topics/db/fetch-modes>`.
-This has a similar purpose to ``select_related``, in that both are designed to
-stop the deluge of database queries that is caused by accessing related
-objects, but the strategy is quite different.
+This method has a similar purpose to :meth:`select_related`, in that both are
+designed to eagerly fetch related objects. However, they work in different
+ways.
``select_related`` works by creating an SQL join and including the fields of
the related object in the ``SELECT`` statement. For this reason,