summaryrefslogtreecommitdiff
path: root/django/contrib
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/contrib
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/contrib')
-rw-r--r--django/contrib/contenttypes/fields.py16
1 files changed, 15 insertions, 1 deletions
diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py
index f98dda1255..aa41eab370 100644
--- a/django/contrib/contenttypes/fields.py
+++ b/django/contrib/contenttypes/fields.py
@@ -16,6 +16,7 @@ from django.db.models.fields.related import (
ReverseManyToOneDescriptor,
lazy_related_operation,
)
+from django.db.models.query import prefetch_related_objects
from django.db.models.query_utils import PathInfo
from django.db.models.sql import AND
from django.db.models.sql.where import WhereNode
@@ -253,6 +254,15 @@ class GenericForeignKeyDescriptor:
return rel_obj
else:
rel_obj = None
+
+ instance._state.fetch_mode.fetch(self, instance)
+ return self.field.get_cached_value(instance)
+
+ def fetch_one(self, instance):
+ f = self.field.model._meta.get_field(self.field.ct_field)
+ ct_id = getattr(instance, f.attname, None)
+ pk_val = getattr(instance, self.field.fk_field)
+ rel_obj = None
if ct_id is not None:
ct = self.field.get_content_type(id=ct_id, using=instance._state.db)
try:
@@ -262,7 +272,11 @@ class GenericForeignKeyDescriptor:
except ObjectDoesNotExist:
pass
self.field.set_cached_value(instance, rel_obj)
- return rel_obj
+
+ def fetch_many(self, instances):
+ is_cached = self.field.is_cached
+ missing_instances = [i for i in instances if not is_cached(i)]
+ return prefetch_related_objects(missing_instances, self.field.name)
def __set__(self, instance, value):
ct = None