summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorJosh Smeaton <josh.smeaton@gmail.com>2015-02-11 16:38:02 +1100
committerJosh Smeaton <josh.smeaton@gmail.com>2015-02-12 08:53:03 +1100
commita6ea62aeafd4512f6d13aeda908f7622776a4537 (patch)
tree27059733fa267e00d7d2bd4058d2f8aef88e2ca0 /django
parent343c0875338128dad162d4806fe908fb31404d14 (diff)
[1.8.x] Refs #14030 -- Improved expression support for python values
Backport of e2d6e14662d780383e18066a3182155fb5b7747b from master
Diffstat (limited to 'django')
-rw-r--r--django/db/backends/base/features.py3
-rw-r--r--django/db/models/expressions.py26
2 files changed, 13 insertions, 16 deletions
diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py
index 4b4d5c6d75..e1c4222410 100644
--- a/django/db/backends/base/features.py
+++ b/django/db/backends/base/features.py
@@ -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
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index c15b095bc2..8e5c4aa533 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -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)