1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Fixed #36025 -- Fixed re-aliasing of iterable (in/range) lookups rhs.

In order for Expression.relabeled_clone to work appropriately its
get_source_expressions method must return all resolvable which wasn't the case
for Lookup when its right-hand-side is "direct" (not a compilable).

While refs #22288 added support for non-literals iterable right-hand-side
lookups it predated the subclassing of Lookup(Expression) refs #27021 which
could have been an opportunity to ensure right-hand-sides are always resolvable
(ValueList and ExpressionList).

Addressing all edge case with non-resolvable right-hand-sides would require
a significant refactor and deprecation of some parts of the Lookup interface so
this patch only focuses on FieldGetDbPrepValueIterableMixin (In and Range
lookups) by making sure that a right-hand-side containing resolvables are dealt
with appropriately during the resolving phase.

Thanks Aashay Amballi for the report.
This commit is contained in:
Simon Charette
2024-12-22 23:00:04 -05:00
committed by Sarah Boyce
parent b13b8684a0
commit 089deb82b9
3 changed files with 49 additions and 3 deletions

View File

@@ -1276,6 +1276,23 @@ class IterableLookupInnerExpressionsTests(TestCase):
queryset = Result.objects.filter(**{lookup: within_experiment_time})
self.assertSequenceEqual(queryset, [r1])
def test_relabeled_clone_rhs(self):
Number.objects.bulk_create([Number(integer=1), Number(integer=2)])
self.assertIs(
Number.objects.filter(
# Ensure iterable of expressions are properly re-labelled on
# subquery pushdown. If the inner query __range right-hand-side
# members are not relabelled they will point at the outer query
# alias and this test will fail.
Exists(
Number.objects.exclude(pk=OuterRef("pk")).filter(
integer__range=(F("integer"), F("integer"))
)
)
).exists(),
True,
)
class FTests(SimpleTestCase):
def test_deepcopy(self):