diff options
| author | Simon Charette <charette.s@gmail.com> | 2025-06-03 22:34:39 -0400 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-06-04 10:48:13 +0200 |
| commit | 3340d4144605bd150906d070ae3e910941fa83c9 (patch) | |
| tree | 69108e27d670e24d1b9a95d9127bdac902cc1fa8 | |
| parent | 0c548e62d0166c559ca59845079c2b70730fcfe7 (diff) | |
[5.2.x] Fixed #36432 -- Fixed a prefetch_related crash on related target subclass queryset.
Regression in 626d77e52a3f247358514bcf51c761283968099c.
Refs #36116.
Thanks Cornelis Poppema for the excellent report.
Backport of 08187c94ed02c45ad40a32244dedeaa7ac71ca87 from main.
| -rw-r--r-- | django/db/models/fields/related_descriptors.py | 5 | ||||
| -rw-r--r-- | docs/releases/5.2.2.txt | 4 | ||||
| -rw-r--r-- | tests/prefetch_related/models.py | 4 | ||||
| -rw-r--r-- | tests/prefetch_related/tests.py | 13 |
4 files changed, 25 insertions, 1 deletions
diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index f0b93e1366..6ef47960dd 100644 --- a/django/db/models/fields/related_descriptors.py +++ b/django/db/models/fields/related_descriptors.py @@ -183,8 +183,11 @@ class ForwardManyToOneDescriptor: rel_obj_attr = self.field.get_foreign_related_value instance_attr = self.field.get_local_related_value instances_dict = {instance_attr(inst): inst for inst in instances} - related_fields = self.field.foreign_related_fields remote_field = self.field.remote_field + related_fields = [ + queryset.query.resolve_ref(field.name).target + for field in self.field.foreign_related_fields + ] queryset = queryset.filter( TupleIn( ColPairs( diff --git a/docs/releases/5.2.2.txt b/docs/releases/5.2.2.txt index 1a363ad55d..56efb69bfb 100644 --- a/docs/releases/5.2.2.txt +++ b/docs/releases/5.2.2.txt @@ -43,3 +43,7 @@ Bugfixes <django.http.HttpRequest.get_preferred_type>` did not account for media type parameters in ``Accept`` headers, reducing specificity in content negotiation (:ticket:`36411`). + +* Fixed a regression in Django 5.2 that caused a crash when using + ``QuerySet.prefetch_related()`` to prefetch a foreign key with a ``Prefetch`` + queryset for a subclass of the foreign target (:ticket:`36432`). diff --git a/tests/prefetch_related/models.py b/tests/prefetch_related/models.py index 2f37cde1c8..888485e169 100644 --- a/tests/prefetch_related/models.py +++ b/tests/prefetch_related/models.py @@ -271,6 +271,10 @@ class Employee(models.Model): ordering = ["id"] +class SelfDirectedEmployee(Employee): + pass + + # Ticket #19607 diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py index b3531cc36f..3c0b5f4505 100644 --- a/tests/prefetch_related/tests.py +++ b/tests/prefetch_related/tests.py @@ -39,6 +39,7 @@ from .models import ( Qualification, Reader, Room, + SelfDirectedEmployee, TaggedItem, Teacher, WordEntry, @@ -435,6 +436,18 @@ class PrefetchRelatedTests(TestDataMixin, TestCase): authors[1].active_favorite_authors, [self.author3, self.author4] ) + def test_prefetch_queryset_child_class(self): + employee = SelfDirectedEmployee.objects.create(name="Foo") + employee.boss = employee + employee.save() + with self.assertNumQueries(2): + retrieved_employee = SelfDirectedEmployee.objects.prefetch_related( + Prefetch("boss", SelfDirectedEmployee.objects.all()) + ).get() + with self.assertNumQueries(0): + self.assertEqual(retrieved_employee, employee) + self.assertEqual(retrieved_employee.boss, retrieved_employee) + class RawQuerySetTests(TestDataMixin, TestCase): def test_basic(self): |
