diff options
| author | Sergey Fedoseev <fedoseev.sergey@gmail.com> | 2017-12-02 07:48:49 +0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-12-01 21:48:49 -0500 |
| commit | cf12257db23fa248c89a3da3f718aa01a50ca659 (patch) | |
| tree | fb01b1c49bc46c87c9cd67eb30b280f8cb665774 | |
| parent | c3e0adcad8d8ba94b33cabd137056166ed36dae0 (diff) | |
Fixed #28863 -- Fixed filter on annotation that contains Q.
| -rw-r--r-- | django/db/models/sql/where.py | 8 | ||||
| -rw-r--r-- | tests/expressions/tests.py | 9 |
2 files changed, 16 insertions, 1 deletions
diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py index 0ca95f7018..1635a686c2 100644 --- a/django/db/models/sql/where.py +++ b/django/db/models/sql/where.py @@ -26,6 +26,7 @@ class WhereNode(tree.Node): contains_aggregate attribute. """ default = AND + resolved = False def split_having(self, negated=False): """ @@ -108,7 +109,7 @@ class WhereNode(tree.Node): # around the inner SQL in the negated case, even if the # inner SQL contains just a single expression. sql_string = 'NOT (%s)' % sql_string - elif len(result) > 1: + elif len(result) > 1 or self.resolved: sql_string = '(%s)' % sql_string return sql_string, result_params @@ -181,6 +182,11 @@ class WhereNode(tree.Node): def is_summary(self): return any(child.is_summary for child in self.children) + def resolve_expression(self, *args, **kwargs): + clone = self.clone() + clone.resolved = True + return clone + class NothingNode: """A node that matches nothing.""" diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 57613d3421..5d54e46c02 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -73,6 +73,15 @@ class BasicExpressionsTests(TestCase): ], ) + @unittest.skipIf(connection.vendor == 'oracle', "Oracle doesn't support using boolean type in SELECT") + def test_filtering_on_annotate_that_uses_q(self): + self.assertEqual( + Company.objects.annotate( + num_employees_check=ExpressionWrapper(Q(num_employees__gt=3), output_field=models.BooleanField()) + ).filter(num_employees_check=True).count(), + 2, + ) + def test_filter_inter_attribute(self): # We can filter on attribute relationships on same model obj, e.g. # find companies where the number of employees is greater |
