diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index c957ffa564..ae0f886107 100644 --- a/django/db/models/query_utils.py +++ b/django/db/models/query_utils.py @@ -40,7 +40,7 @@ class Q(tree.Node): super().__init__(children=[*args, *sorted(kwargs.items())], connector=_connector, negated=_negated) def _combine(self, other, conn): - if not isinstance(other, Q): + if not(isinstance(other, Q) or getattr(other, 'conditional', False) is True): raise TypeError(other) # If the other Q() is empty, ignore it and just use `self`. diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 770a57d66e..9ecc033b6b 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -815,6 +815,14 @@ class BasicExpressionsTests(TestCase): Employee.objects.filter(Exists(is_poc) | Q(salary__lt=15)), [self.example_inc.ceo, self.max], ) + self.assertCountEqual( + Employee.objects.filter(Q(salary__gte=30) & Exists(is_ceo)), + [self.max], + ) + self.assertCountEqual( + Employee.objects.filter(Q(salary__lt=15) | Exists(is_poc)), + [self.example_inc.ceo, self.max], + ) def test_boolean_expression_combined_with_empty_Q(self): is_poc = Company.objects.filter(point_of_contact=OuterRef('pk')) @@ -822,7 +830,9 @@ class BasicExpressionsTests(TestCase): self.gmbh.save() tests = [ Exists(is_poc) & Q(), + Q() & Exists(is_poc), Exists(is_poc) | Q(), + Q() | Exists(is_poc), ] for conditions in tests: with self.subTest(conditions):