mirror of
https://github.com/django/django.git
synced 2025-06-14 16:09:12 +00:00
[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.
This commit is contained in:
parent
0c548e62d0
commit
3340d41446
@ -183,8 +183,11 @@ class ForwardManyToOneDescriptor:
|
|||||||
rel_obj_attr = self.field.get_foreign_related_value
|
rel_obj_attr = self.field.get_foreign_related_value
|
||||||
instance_attr = self.field.get_local_related_value
|
instance_attr = self.field.get_local_related_value
|
||||||
instances_dict = {instance_attr(inst): inst for inst in instances}
|
instances_dict = {instance_attr(inst): inst for inst in instances}
|
||||||
related_fields = self.field.foreign_related_fields
|
|
||||||
remote_field = self.field.remote_field
|
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(
|
queryset = queryset.filter(
|
||||||
TupleIn(
|
TupleIn(
|
||||||
ColPairs(
|
ColPairs(
|
||||||
|
@ -43,3 +43,7 @@ Bugfixes
|
|||||||
<django.http.HttpRequest.get_preferred_type>` did not account for media type
|
<django.http.HttpRequest.get_preferred_type>` did not account for media type
|
||||||
parameters in ``Accept`` headers, reducing specificity in content negotiation
|
parameters in ``Accept`` headers, reducing specificity in content negotiation
|
||||||
(:ticket:`36411`).
|
(: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`).
|
||||||
|
@ -271,6 +271,10 @@ class Employee(models.Model):
|
|||||||
ordering = ["id"]
|
ordering = ["id"]
|
||||||
|
|
||||||
|
|
||||||
|
class SelfDirectedEmployee(Employee):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Ticket #19607
|
# Ticket #19607
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ from .models import (
|
|||||||
Qualification,
|
Qualification,
|
||||||
Reader,
|
Reader,
|
||||||
Room,
|
Room,
|
||||||
|
SelfDirectedEmployee,
|
||||||
TaggedItem,
|
TaggedItem,
|
||||||
Teacher,
|
Teacher,
|
||||||
WordEntry,
|
WordEntry,
|
||||||
@ -435,6 +436,18 @@ class PrefetchRelatedTests(TestDataMixin, TestCase):
|
|||||||
authors[1].active_favorite_authors, [self.author3, self.author4]
|
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):
|
class RawQuerySetTests(TestDataMixin, TestCase):
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user