1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Fixed #34450 -- Fixed multi-valued JOIN reuse when filtering by expressions.

Thanks Roman Odaisky for the report.
This commit is contained in:
Simon Charette 2023-03-31 13:48:02 -04:00 committed by Mariusz Felisiak
parent 79a3ea83b1
commit 0e1aae7a5f
2 changed files with 20 additions and 1 deletions

View File

@ -1373,7 +1373,7 @@ class Query(BaseExpression):
if not getattr(filter_expr, "conditional", False): if not getattr(filter_expr, "conditional", False):
raise TypeError("Cannot filter against a non-conditional expression.") raise TypeError("Cannot filter against a non-conditional expression.")
condition = filter_expr.resolve_expression( condition = filter_expr.resolve_expression(
self, allow_joins=allow_joins, summarize=summarize self, allow_joins=allow_joins, reuse=can_reuse, summarize=summarize
) )
if not isinstance(condition, Lookup): if not isinstance(condition, Lookup):
condition = self.build_lookup(["exact"], condition, True) condition = self.build_lookup(["exact"], condition, True)

View File

@ -1357,6 +1357,9 @@ class LookupQueryingTests(TestCase):
cls.s1 = Season.objects.create(year=1942, gt=1942) cls.s1 = Season.objects.create(year=1942, gt=1942)
cls.s2 = Season.objects.create(year=1842, gt=1942, nulled_text_field="text") cls.s2 = Season.objects.create(year=1842, gt=1942, nulled_text_field="text")
cls.s3 = Season.objects.create(year=2042, gt=1942) cls.s3 = Season.objects.create(year=2042, gt=1942)
Game.objects.create(season=cls.s1, home="NY", away="Boston")
Game.objects.create(season=cls.s1, home="NY", away="Tampa")
Game.objects.create(season=cls.s3, home="Boston", away="Tampa")
def test_annotate(self): def test_annotate(self):
qs = Season.objects.annotate(equal=Exact(F("year"), 1942)) qs = Season.objects.annotate(equal=Exact(F("year"), 1942))
@ -1527,3 +1530,19 @@ class LookupQueryingTests(TestCase):
{"year": 2042, "century": "other"}, {"year": 2042, "century": "other"},
], ],
) )
def test_multivalued_join_reuse(self):
self.assertEqual(
Season.objects.get(Exact(F("games__home"), "NY"), games__away="Boston"),
self.s1,
)
self.assertEqual(
Season.objects.get(Exact(F("games__home"), "NY") & Q(games__away="Boston")),
self.s1,
)
self.assertEqual(
Season.objects.get(
Exact(F("games__home"), "NY") & Exact(F("games__away"), "Boston")
),
self.s1,
)