mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
[1.8.x] Refs #14030 -- Improved expression support for python values
Backport of e2d6e14662 from master
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
from django.db.models.aggregates import StdDev
|
||||
from django.db.models.expressions import Value
|
||||
from django.db.utils import ProgrammingError
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
@@ -229,7 +228,7 @@ class BaseDatabaseFeatures(object):
|
||||
def supports_stddev(self):
|
||||
"""Confirm support for STDDEV and related stats functions."""
|
||||
try:
|
||||
self.connection.ops.check_expression_support(StdDev(Value(1)))
|
||||
self.connection.ops.check_expression_support(StdDev(1))
|
||||
return True
|
||||
except NotImplementedError:
|
||||
return False
|
||||
|
||||
@@ -7,7 +7,7 @@ from django.db.backends import utils as backend_utils
|
||||
from django.db.models import fields
|
||||
from django.db.models.constants import LOOKUP_SEP
|
||||
from django.db.models.query_utils import Q, refs_aggregate
|
||||
from django.utils import timezone
|
||||
from django.utils import six, timezone
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
|
||||
@@ -138,6 +138,13 @@ class BaseExpression(object):
|
||||
def set_source_expressions(self, exprs):
|
||||
assert len(exprs) == 0
|
||||
|
||||
def _parse_expressions(self, *expressions):
|
||||
return [
|
||||
arg if hasattr(arg, 'resolve_expression') else (
|
||||
F(arg) if isinstance(arg, six.string_types) else Value(arg)
|
||||
) for arg in expressions
|
||||
]
|
||||
|
||||
def as_sql(self, compiler, connection):
|
||||
"""
|
||||
Responsible for returning a (sql, [params]) tuple to be included
|
||||
@@ -466,12 +473,6 @@ class Func(ExpressionNode):
|
||||
def set_source_expressions(self, exprs):
|
||||
self.source_expressions = exprs
|
||||
|
||||
def _parse_expressions(self, *expressions):
|
||||
return [
|
||||
arg if hasattr(arg, 'resolve_expression') else F(arg)
|
||||
for arg in expressions
|
||||
]
|
||||
|
||||
def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
|
||||
c = self.copy()
|
||||
c.is_summary = summarize
|
||||
@@ -639,14 +640,14 @@ class Ref(ExpressionNode):
|
||||
class When(ExpressionNode):
|
||||
template = 'WHEN %(condition)s THEN %(result)s'
|
||||
|
||||
def __init__(self, condition=None, then=Value(None), **lookups):
|
||||
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:
|
||||
raise TypeError("__init__() takes either a Q object or lookups as keyword arguments")
|
||||
super(When, self).__init__(output_field=None)
|
||||
self.condition = condition
|
||||
self.result = self._parse_expression(then)
|
||||
self.result = self._parse_expressions(then)[0]
|
||||
|
||||
def __str__(self):
|
||||
return "WHEN %r THEN %r" % (self.condition, self.result)
|
||||
@@ -664,9 +665,6 @@ class When(ExpressionNode):
|
||||
# We're only interested in the fields of the result expressions.
|
||||
return [self.result._output_field_or_none]
|
||||
|
||||
def _parse_expression(self, expression):
|
||||
return expression if hasattr(expression, 'resolve_expression') else F(expression)
|
||||
|
||||
def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
|
||||
c = self.copy()
|
||||
c.is_summary = summarize
|
||||
@@ -713,11 +711,11 @@ class Case(ExpressionNode):
|
||||
def __init__(self, *cases, **extra):
|
||||
if not all(isinstance(case, When) for case in cases):
|
||||
raise TypeError("Positional arguments must all be When objects.")
|
||||
default = extra.pop('default', Value(None))
|
||||
default = extra.pop('default', None)
|
||||
output_field = extra.pop('output_field', None)
|
||||
super(Case, self).__init__(output_field)
|
||||
self.cases = list(cases)
|
||||
self.default = default if hasattr(default, 'resolve_expression') else F(default)
|
||||
self.default = self._parse_expressions(default)[0]
|
||||
|
||||
def __str__(self):
|
||||
return "CASE %s, ELSE %r" % (', '.join(str(c) for c in self.cases), self.default)
|
||||
|
||||
Reference in New Issue
Block a user