Fixed #32450 -- Fixed crash when ANDing/ORing an empty Q() with not pickleable Q().

Regression in bb0b6e5263.
This commit is contained in:
starryrbs 2021-02-18 00:04:59 +08:00 committed by Mariusz Felisiak
parent 1710cdbe79
commit 466920f6d7
2 changed files with 12 additions and 3 deletions

View File

@ -5,7 +5,6 @@ Factored out from django.db.models.query to avoid making the main module very
large and/or so that they can be used by other modules without getting into large and/or so that they can be used by other modules without getting into
circular import difficulties. circular import difficulties.
""" """
import copy
import functools import functools
import inspect import inspect
from collections import namedtuple from collections import namedtuple
@ -46,10 +45,12 @@ class Q(tree.Node):
# If the other Q() is empty, ignore it and just use `self`. # If the other Q() is empty, ignore it and just use `self`.
if not other: if not other:
return copy.deepcopy(self) _, args, kwargs = self.deconstruct()
return type(self)(*args, **kwargs)
# Or if this Q is empty, ignore it and just use `other`. # Or if this Q is empty, ignore it and just use `other`.
elif not self: elif not self:
return copy.deepcopy(other) _, args, kwargs = other.deconstruct()
return type(other)(*args, **kwargs)
obj = type(self)() obj = type(self)()
obj.connector = conn obj.connector = conn

View File

@ -8,6 +8,10 @@ class QTests(SimpleTestCase):
self.assertEqual(q & Q(), q) self.assertEqual(q & Q(), q)
self.assertEqual(Q() & q, q) self.assertEqual(Q() & q, q)
q = Q(x__in={}.keys())
self.assertEqual(q & Q(), q)
self.assertEqual(Q() & q, q)
def test_combine_and_both_empty(self): def test_combine_and_both_empty(self):
self.assertEqual(Q() & Q(), Q()) self.assertEqual(Q() & Q(), Q())
@ -16,6 +20,10 @@ class QTests(SimpleTestCase):
self.assertEqual(q | Q(), q) self.assertEqual(q | Q(), q)
self.assertEqual(Q() | q, q) self.assertEqual(Q() | q, q)
q = Q(x__in={}.keys())
self.assertEqual(q | Q(), q)
self.assertEqual(Q() | q, q)
def test_combine_or_both_empty(self): def test_combine_or_both_empty(self):
self.assertEqual(Q() | Q(), Q()) self.assertEqual(Q() | Q(), Q())