From b43acf22dfa59815a1f4db0558acd98816325f66 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Fri, 8 Dec 2017 10:59:49 -0500 Subject: [PATCH] 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. --- django/db/models/aggregates.py | 4 +--- django/db/models/expressions.py | 2 +- django/db/models/query_utils.py | 1 + django/db/models/sql/where.py | 1 + 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/django/db/models/aggregates.py b/django/db/models/aggregates.py index 3c0434f907..ce4625c1a5 100644 --- a/django/db/models/aggregates.py +++ b/django/db/models/aggregates.py @@ -4,7 +4,6 @@ Classes to represent the definitions of aggregate functions. from django.core.exceptions import FieldError from django.db.models.expressions import Case, Func, Star, When from django.db.models.fields import DecimalField, FloatField, IntegerField -from django.db.models.query_utils import Q __all__ = [ 'Aggregate', 'Avg', 'Count', 'Max', 'Min', 'StdDev', 'Sum', 'Variance', @@ -72,9 +71,8 @@ class Aggregate(Func): else: copy = self.copy() copy.filter = None - condition = When(Q()) 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:]) return super(Aggregate, copy).as_sql(compiler, connection, **extra_context) return super().as_sql(compiler, connection, **extra_context) diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 9ff79f08a4..0109c017da 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -817,7 +817,7 @@ class When(Expression): def __init__(self, condition=None, then=None, **lookups): if lookups and condition is 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") super().__init__(output_field=None) self.condition = condition diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index 8a889264e5..62b67e6131 100644 --- a/django/db/models/query_utils.py +++ b/django/db/models/query_utils.py @@ -53,6 +53,7 @@ class Q(tree.Node): AND = 'AND' OR = 'OR' default = AND + conditional = True def __init__(self, *args, **kwargs): connector = kwargs.pop('_connector', None) diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py index 1635a686c2..d913abab2e 100644 --- a/django/db/models/sql/where.py +++ b/django/db/models/sql/where.py @@ -27,6 +27,7 @@ class WhereNode(tree.Node): """ default = AND resolved = False + conditional = True def split_having(self, negated=False): """