Browse Source

Fixed #34458 -- Fixed QuerySet.defer() crash on attribute names.

Thanks Andrew Cordery for the report.

Regression in b3db6c8dcb5145f7d45eff517bcd96460475c879.
Simon Charette 2 years ago
parent
commit
87c63bd8df
3 changed files with 9 additions and 2 deletions
  1. 2 1
      django/db/models/sql/query.py
  2. 2 1
      docs/releases/4.2.1.txt
  3. 5 0
      tests/defer/tests.py

+ 2 - 1
django/db/models/sql/query.py

@@ -702,7 +702,8 @@ class Query(BaseExpression):
         # by recursively calling this function.
         for field in opts.concrete_fields:
             field_mask = mask.pop(field.name, None)
-            if field_mask is None:
+            field_att_mask = mask.pop(field.attname, None)
+            if field_mask is None and field_att_mask is None:
                 select_mask.setdefault(field, {})
             elif field_mask:
                 if not field.is_relation:

+ 2 - 1
docs/releases/4.2.1.txt

@@ -9,4 +9,5 @@ Django 4.2.1 fixes several bugs in 4.2.
 Bugfixes
 ========
 
-* ...
+* Fixed a regression in Django 4.2 that caused a crash of ``QuerySet.defer()``
+  when deferring fields by attribute names (:ticket:`34458`).

+ 5 - 0
tests/defer/tests.py

@@ -178,6 +178,11 @@ class DeferTests(AssertionMixin, TestCase):
         obj = ShadowChild.objects.defer("name").get()
         self.assertEqual(obj.name, "adonis")
 
+    def test_defer_fk_attname(self):
+        primary = Primary.objects.defer("related_id").get()
+        with self.assertNumQueries(1):
+            self.assertEqual(primary.related_id, self.p1.related_id)
+
 
 class BigChildDeferTests(AssertionMixin, TestCase):
     @classmethod