mirror of
https://github.com/django/django.git
synced 2025-08-22 11:34:33 +00:00
Refs #14030 -- Improved expression support for python values
This commit is contained in:
parent
07cfe1bd82
commit
e2d6e14662
7 changed files with 89 additions and 88 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue