From 9fee229874367beafd532dad6d0f9ff9676ded0b Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Wed, 8 Aug 2018 08:51:20 +0200 Subject: [PATCH] Fixed #29643 -- Fixed crash when combining Q objects with __in lookups and lists. Regression in fc6528b25ab1834be1a478b405bf8f7ec5cf860c. --- django/utils/tree.py | 5 ++++- docs/releases/2.1.1.txt | 3 +++ tests/utils_tests/test_tree.py | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/django/utils/tree.py b/django/utils/tree.py index 2a188acda7..421ad5cd3c 100644 --- a/django/utils/tree.py +++ b/django/utils/tree.py @@ -71,7 +71,10 @@ class Node: ) def __hash__(self): - return hash((self.__class__, self.connector, self.negated) + tuple(self.children)) + return hash((self.__class__, self.connector, self.negated) + tuple([ + tuple(child) if isinstance(child, list) else child + for child in self.children + ])) def add(self, data, conn_type, squash=True): """ diff --git a/docs/releases/2.1.1.txt b/docs/releases/2.1.1.txt index c83c03b9a5..f6e4bc567f 100644 --- a/docs/releases/2.1.1.txt +++ b/docs/releases/2.1.1.txt @@ -18,3 +18,6 @@ Bugfixes * Fixed a regression in Django 2.0 where using ``manage.py test --keepdb`` fails on PostgreSQL if the database exists and the user doesn't have permission to create databases (:ticket:`29613`). + +* Fixed a regression in Django 2.0 where combining ``Q`` objects with ``__in`` + lookups and lists crashed (:ticket:`29643`). diff --git a/tests/utils_tests/test_tree.py b/tests/utils_tests/test_tree.py index 65f49c06a6..c59398aedb 100644 --- a/tests/utils_tests/test_tree.py +++ b/tests/utils_tests/test_tree.py @@ -23,10 +23,12 @@ class NodeTests(unittest.TestCase): node3 = Node(self.node1_children, negated=True) node4 = Node(self.node1_children, connector='OTHER') node5 = Node(self.node1_children) + node6 = Node([['a', 1], ['b', 2]]) self.assertNotEqual(hash(self.node1), hash(self.node2)) self.assertNotEqual(hash(self.node1), hash(node3)) self.assertNotEqual(hash(self.node1), hash(node4)) self.assertEqual(hash(self.node1), hash(node5)) + self.assertEqual(hash(self.node1), hash(node6)) self.assertEqual(hash(self.node2), hash(Node())) def test_len(self):