#34227 closed Bug (fixed)
Multi-level FilteredRelation with select_related() may set wrong related object.
Reported by: | zhu | Owned by: | zhu |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 4.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
test case:
# add to known_related_objects.tests.ExistingRelatedInstancesTests def test_wrong_select_related(self): with self.assertNumQueries(3): p = list(PoolStyle.objects.annotate( tournament_pool=FilteredRelation('pool__tournament__pool'), ).select_related('tournament_pool')) self.assertEqual(p[0].pool.tournament, p[0].tournament_pool.tournament)
result:
====================================================================== FAIL: test_wrong_select_related (known_related_objects.tests.ExistingRelatedInstancesTests.test_wrong_select_related) ---------------------------------------------------------------------- Traceback (most recent call last): File "D:\Work\django\tests\known_related_objects\tests.py", line 171, in test_wrong_select_related self.assertEqual(p[0].pool.tournament, p[0].tournament_pool.tournament) AssertionError: <Tournament: Tournament object (1)> != <PoolStyle: PoolStyle object (1)> ----------------------------------------------------------------------
Change History (7)
comment:1 by , 2 years ago
comment:2 by , 2 years ago
Component: | Uncategorized → Database layer (models, ORM) |
---|---|
Summary: | multi level FilteredRelation with select_related may set wrong related object → Cyclic multi-level FilteredRelation with select_related() may set wrong related object. |
Triage Stage: | Unreviewed → Accepted |
Type: | Uncategorized → Bug |
comment:3 by , 2 years ago
"cyclic" is not the case. Try the test below:
def test_wrong_select_related2(self): with self.assertNumQueries(3): p = list( Tournament.objects.filter(id=self.t2.id).annotate( style=FilteredRelation('pool__another_style'), ).select_related('style') ) self.assertEqual(self.ps3, p[0].style) self.assertEqual(self.p1, p[0].style.pool) self.assertEqual(self.p3, p[0].style.another_pool)
result:
====================================================================== FAIL: test_wrong_select_related2 (known_related_objects.tests.ExistingRelatedInstancesTests.test_wrong_select_related2) ---------------------------------------------------------------------- Traceback (most recent call last): File "/repos/django/tests/known_related_objects/tests.py", line 186, in test_wrong_select_related2 self.assertEqual(self.p3, p[0].style.another_pool) AssertionError: <Pool: Pool object (3)> != <Tournament: Tournament object (2)> ----------------------------------------------------------------------
The query fetch t2 and ps3, then call remote_setter('style', ps3, t2) and local_setter(t2, ps3).
The joins is ['known_related_objects_tournament', 'known_related_objects_pool', 'style'].
The type of the first argument of the local_setter should be joins[-2], but query do not fetch that object, so no available local_setter when len(joins) > 2.
comment:4 by , 2 years ago
Has patch: | set |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:5 by , 2 years ago
Summary: | Cyclic multi-level FilteredRelation with select_related() may set wrong related object. → Multi-level FilteredRelation with select_related() may set wrong related object. |
---|---|
Triage Stage: | Accepted → Ready for checkin |
Note:
See TracTickets
for help on using tickets.
Seems this bug can be fixed by: