summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Fedoseev <fedoseev.sergey@gmail.com>2017-12-02 07:48:49 +0500
committerTim Graham <timograham@gmail.com>2017-12-01 21:49:01 -0500
commit70da0420c2294cf9c851dc7703c8b729f1ed8956 (patch)
tree885de4f86d15f635caf413f843f7654318833376
parent4dc35e126d8461589b4b4bc47b6f6bd6cc4a1455 (diff)
[2.0.x] Fixed #28863 -- Fixed filter on annotation that contains Q.
Backport of cf12257db23fa248c89a3da3f718aa01a50ca659 from master
-rw-r--r--django/db/models/sql/where.py8
-rw-r--r--tests/expressions/tests.py9
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 ca331aeb03..c0a36221a2 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