summaryrefslogtreecommitdiff
path: root/django/db/models/fetch_modes.py
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 /django/db/models/fetch_modes.py
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 'django/db/models/fetch_modes.py')
-rw-r--r--django/db/models/fetch_modes.py52
1 files changed, 52 insertions, 0 deletions
diff --git a/django/db/models/fetch_modes.py b/django/db/models/fetch_modes.py
new file mode 100644
index 0000000000..a22ccd8a23
--- /dev/null
+++ b/django/db/models/fetch_modes.py
@@ -0,0 +1,52 @@
+from django.core.exceptions import FieldFetchBlocked
+
+
+class FetchMode:
+ __slots__ = ()
+
+ track_peers = False
+
+ def fetch(self, fetcher, instance):
+ raise NotImplementedError("Subclasses must implement this method.")
+
+
+class FetchOne(FetchMode):
+ __slots__ = ()
+
+ def fetch(self, fetcher, instance):
+ fetcher.fetch_one(instance)
+
+
+FETCH_ONE = FetchOne()
+
+
+class FetchPeers(FetchMode):
+ __slots__ = ()
+
+ track_peers = True
+
+ def fetch(self, fetcher, instance):
+ instances = [
+ peer
+ for peer_weakref in instance._state.peers
+ if (peer := peer_weakref()) is not None
+ ]
+ if len(instances) > 1:
+ fetcher.fetch_many(instances)
+ else:
+ fetcher.fetch_one(instance)
+
+
+FETCH_PEERS = FetchPeers()
+
+
+class Raise(FetchMode):
+ __slots__ = ()
+
+ def fetch(self, fetcher, instance):
+ klass = instance.__class__.__qualname__
+ field_name = fetcher.field.name
+ raise FieldFetchBlocked(f"Fetching of {klass}.{field_name} blocked.") from None
+
+
+RAISE = Raise()