Fixed #35050 -- Fixed prefixing field names in FilteredRelation().

Thanks Mark Zorn for the report.

Regression in 59f4754704.
This commit is contained in:
David Wobrock 2023-12-21 23:20:36 +01:00 committed by Mariusz Felisiak
parent 623597c786
commit 14917c9ae2
4 changed files with 45 additions and 2 deletions

View File

@ -94,14 +94,16 @@ def get_child_with_renamed_prefix(prefix, replacement, child):
return rename_prefix_from_q(prefix, replacement, child)
if isinstance(child, tuple):
lhs, rhs = child
lhs = lhs.replace(prefix, replacement, 1)
if lhs.startswith(prefix + LOOKUP_SEP):
lhs = lhs.replace(prefix, replacement, 1)
if not isinstance(rhs, F) and hasattr(rhs, "resolve_expression"):
rhs = get_child_with_renamed_prefix(prefix, replacement, rhs)
return lhs, rhs
if isinstance(child, F):
child = child.copy()
child.name = child.name.replace(prefix, replacement, 1)
if child.name.startswith(prefix + LOOKUP_SEP):
child.name = child.name.replace(prefix, replacement, 1)
elif hasattr(child, "resolve_expression"):
child = child.copy()
child.set_source_expressions(

View File

@ -29,3 +29,6 @@ Bugfixes
overflow the page and become non-interactive (:ticket:`35012`).
* Added compatibility for ``oracledb`` 2.0.0 (:ticket:`35054`).
* Fixed a regression in Django 5.0 where querysets referenced incorrect field
names from ``FilteredRelation()`` (:ticket:`35050`).

View File

@ -36,6 +36,8 @@ class Book(models.Model):
related_query_name="book",
)
editor = models.ForeignKey(Editor, models.CASCADE)
number_editor = models.IntegerField(default=-1)
editor_number = models.IntegerField(default=-2)
generic_author = GenericRelation(Author)
state = models.CharField(max_length=9, choices=STATES, default=AVAILABLE)

View File

@ -792,6 +792,42 @@ class FilteredRelationTests(TestCase):
).filter(my_books__isnull=True)
self.assertSequenceEqual(qs, [])
def test_conditional_expression_rhs_contains_relation_name(self):
qs = Book.objects.annotate(
rel=FilteredRelation(
"editor",
condition=Q(id=1 * F("number_editor")),
)
).filter(rel__isnull=True)
self.assertSequenceEqual(qs, [])
def test_conditional_expression_rhs_startswith_relation_name(self):
qs = Book.objects.annotate(
rel=FilteredRelation(
"editor",
condition=Q(id=1 * F("editor_number")),
)
).filter(rel__isnull=True)
self.assertSequenceEqual(qs, [])
def test_conditional_expression_lhs_startswith_relation_name(self):
qs = Book.objects.annotate(
rel=FilteredRelation(
"editor",
condition=Q(editor_number__gt=1),
)
).filter(rel__isnull=True)
self.assertSequenceEqual(qs, [])
def test_conditional_expression_lhs_contains_relation_name(self):
qs = Book.objects.annotate(
rel=FilteredRelation(
"editor",
condition=Q(number_editor__gt=1),
)
).filter(rel__isnull=True)
self.assertSequenceEqual(qs, [])
class FilteredRelationAggregationTests(TestCase):
@classmethod