1
0
mirror of https://github.com/django/django.git synced 2025-06-05 11:39:13 +00:00

Refs #27849 -- Removed empty Q() hack in filtered Aggregate.as_sql().

This required allowing WhereNode to be provided as When(condition).

This was made possible by cf12257db23fa248c89a3da3f718aa01a50ca659.
This commit is contained in:
Simon Charette 2017-12-08 10:59:49 -05:00 committed by Tim Graham
parent fff86cfa46
commit b43acf22df
4 changed files with 4 additions and 4 deletions

View File

@ -4,7 +4,6 @@ Classes to represent the definitions of aggregate functions.
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
from django.db.models.expressions import Case, Func, Star, When from django.db.models.expressions import Case, Func, Star, When
from django.db.models.fields import DecimalField, FloatField, IntegerField from django.db.models.fields import DecimalField, FloatField, IntegerField
from django.db.models.query_utils import Q
__all__ = [ __all__ = [
'Aggregate', 'Avg', 'Count', 'Max', 'Min', 'StdDev', 'Sum', 'Variance', 'Aggregate', 'Avg', 'Count', 'Max', 'Min', 'StdDev', 'Sum', 'Variance',
@ -72,9 +71,8 @@ class Aggregate(Func):
else: else:
copy = self.copy() copy = self.copy()
copy.filter = None copy.filter = None
condition = When(Q())
source_expressions = copy.get_source_expressions() source_expressions = copy.get_source_expressions()
condition.set_source_expressions([self.filter, source_expressions[0]]) condition = When(self.filter, then=source_expressions[0])
copy.set_source_expressions([Case(condition)] + source_expressions[1:]) copy.set_source_expressions([Case(condition)] + source_expressions[1:])
return super(Aggregate, copy).as_sql(compiler, connection, **extra_context) return super(Aggregate, copy).as_sql(compiler, connection, **extra_context)
return super().as_sql(compiler, connection, **extra_context) return super().as_sql(compiler, connection, **extra_context)

View File

@ -817,7 +817,7 @@ class When(Expression):
def __init__(self, condition=None, then=None, **lookups): def __init__(self, condition=None, then=None, **lookups):
if lookups and condition is None: if lookups and condition is None:
condition, lookups = Q(**lookups), None condition, lookups = Q(**lookups), None
if condition is None or not isinstance(condition, Q) or lookups: if condition is None or not getattr(condition, 'conditional', False) or lookups:
raise TypeError("__init__() takes either a Q object or lookups as keyword arguments") raise TypeError("__init__() takes either a Q object or lookups as keyword arguments")
super().__init__(output_field=None) super().__init__(output_field=None)
self.condition = condition self.condition = condition

View File

@ -53,6 +53,7 @@ class Q(tree.Node):
AND = 'AND' AND = 'AND'
OR = 'OR' OR = 'OR'
default = AND default = AND
conditional = True
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
connector = kwargs.pop('_connector', None) connector = kwargs.pop('_connector', None)

View File

@ -27,6 +27,7 @@ class WhereNode(tree.Node):
""" """
default = AND default = AND
resolved = False resolved = False
conditional = True
def split_having(self, negated=False): def split_having(self, negated=False):
""" """