From e097e8a12f21a4e92594830f1ad1942b31916d0f Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 29 Nov 2023 09:35:34 +0000 Subject: Fixed #28586 -- Added model field fetch modes. May your database queries be much reduced with minimal effort. co-authored-by: Andreas Pelme co-authored-by: Simon Charette co-authored-by: Jacob Walls --- django/contrib/contenttypes/fields.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'django/contrib/contenttypes/fields.py') 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 -- cgit v1.3