[2.0.x] Fixed #28863 -- Fixed filter on annotation that contains Q.

Backport of cf12257db2 from master
This commit is contained in:
Sergey Fedoseev 2017-12-02 07:48:49 +05:00 committed by Tim Graham
parent 4dc35e126d
commit 70da0420c2
2 changed files with 16 additions and 1 deletions

View File

@ -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."""

View File

@ -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