summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wobrock <david.wobrock@gmail.com>2023-12-21 23:20:36 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-12-23 18:33:07 +0100
commit9aad44150fa7632b894c8b1d1cb9c6dde131b577 (patch)
tree94660e9b8c6e5eb2fd9c9b055f37d8a910b0cf9c
parent42c31f867fa75d52bbbb4b39478f982fbe010ae1 (diff)
[5.0.x] Fixed #35050 -- Fixed prefixing field names in FilteredRelation().
Thanks Mark Zorn for the report. Regression in 59f475470494ce5b8cbff816b1e5dafcbd10a3a3. Backport of 14917c9ae272f47d23401100faa6cefa8e1728bf from main
-rw-r--r--django/db/models/sql/query.py6
-rw-r--r--docs/releases/5.0.1.txt3
-rw-r--r--tests/filtered_relation/models.py2
-rw-r--r--tests/filtered_relation/tests.py36
4 files changed, 45 insertions, 2 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index f04b1c4cc3..3320f91fa1 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -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(
diff --git a/docs/releases/5.0.1.txt b/docs/releases/5.0.1.txt
index 592454e893..15b735b42e 100644
--- a/docs/releases/5.0.1.txt
+++ b/docs/releases/5.0.1.txt
@@ -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`).
diff --git a/tests/filtered_relation/models.py b/tests/filtered_relation/models.py
index d34a86305f..765d4956e2 100644
--- a/tests/filtered_relation/models.py
+++ b/tests/filtered_relation/models.py
@@ -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)
diff --git a/tests/filtered_relation/tests.py b/tests/filtered_relation/tests.py
index 5a21a47f36..19714e8443 100644
--- a/tests/filtered_relation/tests.py
+++ b/tests/filtered_relation/tests.py
@@ -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