Browse Source

Fixed #36109 -- Fixed RecursionError when stacking FilteredRelation joins.

Peter DeVita 2 months ago
parent
commit
8eca4077f6
3 changed files with 25 additions and 0 deletions
  1. 1 0
      AUTHORS
  2. 2 0
      django/db/models/sql/query.py
  3. 22 0
      tests/filtered_relation/tests.py

+ 1 - 0
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>

+ 2 - 0
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):

+ 22 - 0
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(