summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Delaby <nicolas.delaby@infarm.com>2024-01-23 11:51:24 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2024-01-29 20:29:49 +0100
commit820c5f1bacd41713bd30d8b5fefb66752ff15c4c (patch)
treed5182900a739e598b967523537902ddca7035654
parenta5365339eaee043895a79dbbdd7462f1399136e5 (diff)
Fixed #35135 -- Made FilteredRelation raise ValueError on querysets as rhs.
Regression in 59f475470494ce5b8cbff816b1e5dafcbd10a3a3.
-rw-r--r--django/db/models/sql/query.py10
-rw-r--r--docs/releases/5.0.2.txt5
-rw-r--r--tests/filtered_relation/tests.py10
3 files changed, 25 insertions, 0 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 6e8813b5e7..5100869b34 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -91,6 +91,8 @@ def get_children_from_q(q):
def get_child_with_renamed_prefix(prefix, replacement, child):
+ from django.db.models.query import QuerySet
+
if isinstance(child, Node):
return rename_prefix_from_q(prefix, replacement, child)
if isinstance(child, tuple):
@@ -105,6 +107,14 @@ def get_child_with_renamed_prefix(prefix, replacement, child):
child = child.copy()
if child.name.startswith(prefix + LOOKUP_SEP):
child.name = child.name.replace(prefix, replacement, 1)
+ elif isinstance(child, QuerySet):
+ # QuerySet may contain OuterRef() references which cannot work properly
+ # without repointing to the filtered annotation and will spawn a
+ # different JOIN. Always raise ValueError instead of providing partial
+ # support in other cases.
+ raise ValueError(
+ "Passing a QuerySet within a FilteredRelation is not supported."
+ )
elif hasattr(child, "resolve_expression"):
child = child.copy()
child.set_source_expressions(
diff --git a/docs/releases/5.0.2.txt b/docs/releases/5.0.2.txt
index c795049c73..8e2d648ecc 100644
--- a/docs/releases/5.0.2.txt
+++ b/docs/releases/5.0.2.txt
@@ -19,3 +19,8 @@ Bugfixes
* Fixed a bug in Django 5.0 that caused a crash of ``Model.full_clean()`` on
models with a ``GeneratedField`` (:ticket:`35127`).
+
+* Fixed a regression in Django 5.0 that caused a crash of
+ ``FilteredRelation()`` with querysets as right-hand sides (:ticket:`35135`).
+ ``FilteredRelation()`` now raises a ``ValueError`` on querysets as right-hand
+ sides.
diff --git a/tests/filtered_relation/tests.py b/tests/filtered_relation/tests.py
index 19714e8443..82caba8662 100644
--- a/tests/filtered_relation/tests.py
+++ b/tests/filtered_relation/tests.py
@@ -828,6 +828,16 @@ class FilteredRelationTests(TestCase):
).filter(rel__isnull=True)
self.assertSequenceEqual(qs, [])
+ def test_conditional_expression_does_not_support_queryset(self):
+ msg = "Passing a QuerySet within a FilteredRelation is not supported."
+ with self.assertRaisesMessage(ValueError, msg):
+ Author.objects.annotate(
+ poem_book=FilteredRelation(
+ "book",
+ condition=Q(book__in=Book.objects.filter(title__istartswith="a")),
+ ),
+ ).filter(poem_book__isnull=False)
+
class FilteredRelationAggregationTests(TestCase):
@classmethod