mirror of https://github.com/django/django.git
Fixed #34227 -- Fixed QuerySet.select_related() with multi-level FilteredRelation.
This commit is contained in:
parent
ef85b6bf0b
commit
d3c93cdc59
|
@ -1274,6 +1274,9 @@ class SQLCompiler:
|
||||||
if from_obj:
|
if from_obj:
|
||||||
final_field.remote_field.set_cached_value(from_obj, obj)
|
final_field.remote_field.set_cached_value(from_obj, obj)
|
||||||
|
|
||||||
|
def local_setter_noop(obj, from_obj):
|
||||||
|
pass
|
||||||
|
|
||||||
def remote_setter(name, obj, from_obj):
|
def remote_setter(name, obj, from_obj):
|
||||||
setattr(from_obj, name, obj)
|
setattr(from_obj, name, obj)
|
||||||
|
|
||||||
|
@ -1295,7 +1298,11 @@ class SQLCompiler:
|
||||||
"model": model,
|
"model": model,
|
||||||
"field": final_field,
|
"field": final_field,
|
||||||
"reverse": True,
|
"reverse": True,
|
||||||
"local_setter": partial(local_setter, final_field),
|
"local_setter": (
|
||||||
|
partial(local_setter, final_field)
|
||||||
|
if len(joins) <= 2
|
||||||
|
else local_setter_noop
|
||||||
|
),
|
||||||
"remote_setter": partial(remote_setter, name),
|
"remote_setter": partial(remote_setter, name),
|
||||||
"from_parent": from_parent,
|
"from_parent": from_parent,
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,3 +164,23 @@ class ExistingRelatedInstancesTests(TestCase):
|
||||||
)
|
)
|
||||||
self.assertIs(ps[0], ps[0].pool_1.poolstyle)
|
self.assertIs(ps[0], ps[0].pool_1.poolstyle)
|
||||||
self.assertIs(ps[0], ps[0].pool_2.another_style)
|
self.assertIs(ps[0], ps[0].pool_2.another_style)
|
||||||
|
|
||||||
|
def test_multilevel_reverse_fk_cyclic_select_related(self):
|
||||||
|
with self.assertNumQueries(3):
|
||||||
|
p = list(
|
||||||
|
PoolStyle.objects.annotate(
|
||||||
|
tournament_pool=FilteredRelation("pool__tournament__pool"),
|
||||||
|
).select_related("tournament_pool", "tournament_pool__tournament")
|
||||||
|
)
|
||||||
|
self.assertEqual(p[0].tournament_pool.tournament, p[0].pool.tournament)
|
||||||
|
|
||||||
|
def test_multilevel_reverse_fk_select_related(self):
|
||||||
|
with self.assertNumQueries(2):
|
||||||
|
p = list(
|
||||||
|
Tournament.objects.filter(id=self.t2.id)
|
||||||
|
.annotate(
|
||||||
|
style=FilteredRelation("pool__another_style"),
|
||||||
|
)
|
||||||
|
.select_related("style")
|
||||||
|
)
|
||||||
|
self.assertEqual(p[0].style.another_pool, self.p3)
|
||||||
|
|
Loading…
Reference in New Issue