1
0
mirror of https://github.com/django/django.git synced 2024-12-22 09:05:43 +00:00

Fixed #34226 -- Fixed QuerySet.select_related() with multiple FilteredRelations to the OneToOneField.

This commit is contained in:
朱穆穆 2022-12-26 14:13:44 +08:00 committed by Mariusz Felisiak
parent 48b6108e50
commit bbeeb45161
3 changed files with 22 additions and 2 deletions

View File

@ -1265,7 +1265,7 @@ class SQLCompiler:
)
get_related_klass_infos(klass_info, next_klass_infos)
def local_setter(obj, from_obj):
def local_setter(final_field, obj, from_obj):
# Set a reverse fk object when relation is non-empty.
if from_obj:
final_field.remote_field.set_cached_value(from_obj, obj)
@ -1291,7 +1291,7 @@ class SQLCompiler:
"model": model,
"field": final_field,
"reverse": True,
"local_setter": local_setter,
"local_setter": partial(local_setter, final_field),
"remote_setter": partial(remote_setter, name),
"from_parent": from_parent,
}

View File

@ -24,3 +24,6 @@ class Pool(models.Model):
class PoolStyle(models.Model):
name = models.CharField(max_length=30)
pool = models.OneToOneField(Pool, models.CASCADE)
another_pool = models.OneToOneField(
Pool, models.CASCADE, null=True, related_name="another_style"
)

View File

@ -1,3 +1,4 @@
from django.db.models import FilteredRelation
from django.test import TestCase
from .models import Organiser, Pool, PoolStyle, Tournament
@ -23,6 +24,9 @@ class ExistingRelatedInstancesTests(TestCase):
)
cls.ps1 = PoolStyle.objects.create(name="T1 Pool 2 Style", pool=cls.p2)
cls.ps2 = PoolStyle.objects.create(name="T2 Pool 1 Style", pool=cls.p3)
cls.ps3 = PoolStyle.objects.create(
name="T1 Pool 1/3 Style", pool=cls.p1, another_pool=cls.p3
)
def test_foreign_key(self):
with self.assertNumQueries(2):
@ -147,3 +151,16 @@ class ExistingRelatedInstancesTests(TestCase):
pools = list(Pool.objects.prefetch_related("poolstyle").order_by("pk"))
self.assertIs(pools[1], pools[1].poolstyle.pool)
self.assertIs(pools[2], pools[2].poolstyle.pool)
def test_reverse_fk_select_related_multiple(self):
with self.assertNumQueries(1):
ps = list(
PoolStyle.objects.annotate(
pool_1=FilteredRelation("pool"),
pool_2=FilteredRelation("another_pool"),
)
.select_related("pool_1", "pool_2")
.order_by("-pk")
)
self.assertIs(ps[0], ps[0].pool_1.poolstyle)
self.assertIs(ps[0], ps[0].pool_2.another_style)