summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/utils/tree.py2
-rw-r--r--docs/releases/3.2.3.txt3
-rw-r--r--tests/queries/tests.py4
-rw-r--r--tests/utils_tests/test_tree.py5
4 files changed, 13 insertions, 1 deletions
diff --git a/django/utils/tree.py b/django/utils/tree.py
index 302cd37d5f..af17be939c 100644
--- a/django/utils/tree.py
+++ b/django/utils/tree.py
@@ -90,7 +90,7 @@ class Node:
If `squash` is False the data is prepared and added as a child to
this tree without further logic.
"""
- if data in self.children:
+ if self.connector == conn_type and data in self.children:
return data
if not squash:
self.children.append(data)
diff --git a/docs/releases/3.2.3.txt b/docs/releases/3.2.3.txt
index 14a143b203..315678b92a 100644
--- a/docs/releases/3.2.3.txt
+++ b/docs/releases/3.2.3.txt
@@ -10,3 +10,6 @@ Bugfixes
========
* Prepared for ``mysqlclient`` > 2.0.3 support (:ticket:`32732`).
+
+* Fixed a regression in Django 3.2 that caused the incorrect filtering of
+ querysets combined with the ``|`` operator (:ticket:`32717`).
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index 9350e3e37e..877d758904 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -1338,6 +1338,10 @@ class Queries4Tests(TestCase):
self.assertEqual(len(combined), 1)
self.assertEqual(combined[0].name, 'a1')
+ def test_combine_or_filter_reuse(self):
+ combined = Author.objects.filter(name='a1') | Author.objects.filter(name='a3')
+ self.assertEqual(combined.get(name='a1'), self.a1)
+
def test_join_reuse_order(self):
# Join aliases are reused in order. This shouldn't raise AssertionError
# because change_map contains a circular reference (#26522).
diff --git a/tests/utils_tests/test_tree.py b/tests/utils_tests/test_tree.py
index 154678ff57..279e8813b9 100644
--- a/tests/utils_tests/test_tree.py
+++ b/tests/utils_tests/test_tree.py
@@ -57,6 +57,11 @@ class NodeTests(unittest.TestCase):
self.assertEqual(len(self.node1) + 1, len(node3))
self.assertEqual(str(node3), "(DEFAULT: ('a', 1), ('b', 2), ('c', 3))")
+ def test_add_eq_child_mixed_connector(self):
+ node = Node(['a', 'b'], 'OR')
+ self.assertEqual(node.add('a', 'AND'), 'a')
+ self.assertEqual(node, Node([Node(['a', 'b'], 'OR'), 'a'], 'AND'))
+
def test_negate(self):
# negated is False by default
self.assertFalse(self.node1.negated)