Fixed #28863 -- Fixed filter on annotation that contains Q.
This commit is contained in:
parent
c3e0adcad8
commit
cf12257db2
|
@ -26,6 +26,7 @@ class WhereNode(tree.Node):
|
||||||
contains_aggregate attribute.
|
contains_aggregate attribute.
|
||||||
"""
|
"""
|
||||||
default = AND
|
default = AND
|
||||||
|
resolved = False
|
||||||
|
|
||||||
def split_having(self, negated=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
|
# around the inner SQL in the negated case, even if the
|
||||||
# inner SQL contains just a single expression.
|
# inner SQL contains just a single expression.
|
||||||
sql_string = 'NOT (%s)' % sql_string
|
sql_string = 'NOT (%s)' % sql_string
|
||||||
elif len(result) > 1:
|
elif len(result) > 1 or self.resolved:
|
||||||
sql_string = '(%s)' % sql_string
|
sql_string = '(%s)' % sql_string
|
||||||
return sql_string, result_params
|
return sql_string, result_params
|
||||||
|
|
||||||
|
@ -181,6 +182,11 @@ class WhereNode(tree.Node):
|
||||||
def is_summary(self):
|
def is_summary(self):
|
||||||
return any(child.is_summary for child in self.children)
|
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:
|
class NothingNode:
|
||||||
"""A node that matches nothing."""
|
"""A node that matches nothing."""
|
||||||
|
|
|
@ -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):
|
def test_filter_inter_attribute(self):
|
||||||
# We can filter on attribute relationships on same model obj, e.g.
|
# We can filter on attribute relationships on same model obj, e.g.
|
||||||
# find companies where the number of employees is greater
|
# find companies where the number of employees is greater
|
||||||
|
|
Loading…
Reference in New Issue