summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2021-09-30 11:26:17 +0200
committerGitHub <noreply@github.com>2021-09-30 11:26:17 +0200
commit903aaa35e5ceaa33bfc9b19b7f6da65ce5a91dd4 (patch)
treee11e4698c812238fda4177459904145cbbb1176a
parentdd1fa3a31b4680c0d3712e6ae122b878138580c7 (diff)
Fixed #33159 -- Reverted "Fixed #32970 -- Changed WhereNode.clone() to create a shallow copy of children."
This reverts commit e441847ecae99dd1ccd0d9ce76dbcff51afa863c. A shallow copy is not enough because querysets can be reused and evaluated in nested nodes, which shouldn't mutate JOIN aliases. Thanks Michal Čihař for the report.
-rw-r--r--django/db/models/sql/where.py6
-rw-r--r--tests/queries/tests.py6
2 files changed, 11 insertions, 1 deletions
diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py
index 160d5733b8..50ff13be75 100644
--- a/django/db/models/sql/where.py
+++ b/django/db/models/sql/where.py
@@ -148,7 +148,11 @@ class WhereNode(tree.Node):
clone = self.__class__._new_instance(
children=None, connector=self.connector, negated=self.negated,
)
- clone.children = self.children[:]
+ for child in self.children:
+ if hasattr(child, 'clone'):
+ clone.children.append(child.clone())
+ else:
+ clone.children.append(child)
return clone
def relabeled_clone(self, change_map):
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index fa87e7859c..9c1b41a395 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -1663,6 +1663,12 @@ class Queries5Tests(TestCase):
'bar %s'
)
+ def test_queryset_reuse(self):
+ # Using querysets doesn't mutate aliases.
+ authors = Author.objects.filter(Q(name='a1') | Q(name='nonexistent'))
+ self.assertEqual(Ranking.objects.filter(author__in=authors).get(), self.rank3)
+ self.assertEqual(authors.count(), 1)
+
class SelectRelatedTests(TestCase):
def test_tickets_3045_3288(self):