summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter DeVita <mewtwo2643@yahoo.com>2025-01-17 13:22:24 -0500
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-01-27 10:34:16 +0100
commit720ef7a867eab1491f5789fe39b3431a498b2b89 (patch)
tree851849e386b06392dad3ef58fcef148ba7cf0b1c
parentb285cc787ecfd6d8305ee9c8cb84edbf95e59f36 (diff)
[5.2.x] Fixed #36109 -- Fixed RecursionError when stacking FilteredRelation joins.
Backport of 8eca4077f60fa0705ecfd9437c9ceaeef7a3808b from main.
-rw-r--r--AUTHORS1
-rw-r--r--django/db/models/sql/query.py2
-rw-r--r--tests/filtered_relation/tests.py22
3 files changed, 25 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
index 9d8956bda0..0648241267 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -823,6 +823,7 @@ answer newbie questions, and generally made Django that much better:
Petar Marić <http://www.petarmaric.com/>
Pete Crosier <pete.crosier@gmail.com>
peter@mymart.com
+ Peter DeVita <pmdevita2643@gmail.com>
Peter Sheats <sheats@gmail.com>
Peter van Kampen
Peter Zsoldos <http://zsoldosp.eu>
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 6fbf854e67..ddf6c891fa 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1946,6 +1946,8 @@ class Query(BaseExpression):
reuse = can_reuse if join.m2m else None
alias = self.join(connection, reuse=reuse)
joins.append(alias)
+ if join.filtered_relation and can_reuse is not None:
+ can_reuse.add(alias)
return JoinInfo(final_field, targets, opts, joins, path, final_transformer)
def trim_joins(self, targets, joins, path):
diff --git a/tests/filtered_relation/tests.py b/tests/filtered_relation/tests.py
index cbf77752df..a9c6e00567 100644
--- a/tests/filtered_relation/tests.py
+++ b/tests/filtered_relation/tests.py
@@ -582,6 +582,28 @@ class FilteredRelationTests(TestCase):
lambda x: (x.author, x.book_title, x.preferred_by_author_pk),
)
+ def test_three_level_nested_chained_relations(self):
+ borrower = Borrower.objects.create(name="Jenny")
+ Reservation.objects.create(
+ borrower=borrower,
+ book=self.book1,
+ state=Reservation.STOPPED,
+ )
+ qs = Author.objects.annotate(
+ my_books=FilteredRelation("book"),
+ my_reserved_books=FilteredRelation(
+ "my_books__reservation",
+ condition=Q(my_books__reservation__state=Reservation.STOPPED),
+ ),
+ my_readers=FilteredRelation(
+ "my_reserved_books__borrower",
+ condition=Q(my_reserved_books__borrower=borrower),
+ ),
+ )
+ self.assertSequenceEqual(
+ qs.filter(my_readers=borrower).values_list("name", flat=True), ["Alice"]
+ )
+
def test_deep_nested_foreign_key(self):
qs = (
Book.objects.annotate(