From 040bb3eba72eb45020dd025d3f83094a0fcaf22f Mon Sep 17 00:00:00 2001 From: Samriddha9619 Date: Mon, 5 Jan 2026 11:18:40 +0530 Subject: Fixed #35442 -- Prevented N+1 queries in RelatedManager with only(). Co-authored-by: Simon Charette --- django/db/models/query.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'django') diff --git a/django/db/models/query.py b/django/db/models/query.py index 73d6717bce..5649a83428 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -114,16 +114,15 @@ class ModelIterable(BaseIterable): ( field, related_objs, - operator.attrgetter( - *[ - ( - field.attname - if from_field == "self" - else queryset.model._meta.get_field(from_field).attname - ) - for from_field in field.from_fields - ] - ), + attnames := [ + ( + field.attname + if from_field == "self" + else queryset.model._meta.get_field(from_field).attname + ) + for from_field in field.from_fields + ], + operator.attrgetter(*attnames), ) for field, related_objs in queryset._known_related_objects.items() ] @@ -145,10 +144,14 @@ class ModelIterable(BaseIterable): setattr(obj, attr_name, row[col_pos]) # Add the known related objects to the model. - for field, rel_objs, rel_getter in known_related_objects: + for field, rel_objs, rel_attnames, rel_getter in known_related_objects: # Avoid overwriting objects loaded by, e.g., select_related(). if field.is_cached(obj): continue + # Avoid fetching potentially deferred attributes that would + # result in unexpected queries. + if any(attname not in obj.__dict__ for attname in rel_attnames): + continue rel_obj_id = rel_getter(obj) try: rel_obj = rel_objs[rel_obj_id] -- cgit v1.3