class Case
from django.db.models.expressions import Case
An SQL searched CASE expression: CASE WHEN n > 0 THEN 'positive' WHEN n < 0 THEN 'negative' ELSE 'zero' END
Ancestors (MRO)
- builtins.object
- django.db.models.expressions.Combinable
- django.db.models.expressions.BaseExpression
- django.db.models.expressions.Expression
- django.db.models.expressions.SQLiteNumericMixin
- django.db.models.expressions.Case
Attribute | Value | Defined in |
---|---|---|
ADD |
+ |
django.db.models.expressions.Combinable |
BITAND |
& |
django.db.models.expressions.Combinable |
BITLEFTSHIFT |
<< |
django.db.models.expressions.Combinable |
BITOR |
| |
django.db.models.expressions.Combinable |
BITRIGHTSHIFT |
>> |
django.db.models.expressions.Combinable |
BITXOR |
# |
django.db.models.expressions.Combinable |
DIV |
/ |
django.db.models.expressions.Combinable |
MOD |
%% |
django.db.models.expressions.Combinable |
MUL |
* |
django.db.models.expressions.Combinable |
POW |
^ |
django.db.models.expressions.Combinable |
SUB |
- |
django.db.models.expressions.Combinable |
allowed_default |
False |
django.db.models.expressions.BaseExpression |
case_joiner |
|
django.db.models.expressions.Case |
empty_result_set_value |
NotImplemented |
django.db.models.expressions.BaseExpression |
filterable |
True |
django.db.models.expressions.BaseExpression |
is_summary |
False |
django.db.models.expressions.BaseExpression |
template |
CASE %(cases)s ELSE %(default)s END |
django.db.models.expressions.Case |
window_compatible |
False |
django.db.models.expressions.BaseExpression |
def allowed_default(self)
django.db.models.expressions.Case
def as_sql(self, compiler, connection, template=None, case_joiner=None, **extra_context)
django.db.models.expressions.Case
django.db.models.expressions.Case
Responsible for returning a (sql, [params]) tuple to be included in the current query. Different backends can provide their own implementation, by providing an `as_{vendor}` method and patching the Expression: ``` def override_as_sql(self, compiler, connection): # custom logic return super().as_sql(compiler, connection) setattr(Expression, 'as_' + connection.vendor, override_as_sql) ``` Arguments: * compiler: the query compiler responsible for generating the query. Must have a compile method, returning a (sql, [params]) tuple. Calling compiler(value) will return a quoted `value`. * connection: the database connection used for the current query. Return: (sql, params) Where `sql` is a string containing ordered sql parameters to be replaced with the elements of the list `params`.
def as_sql(
self, compiler, connection, template=None, case_joiner=None, **extra_context
):
connection.ops.check_expression_support(self)
if not self.cases:
return compiler.compile(self.default)
template_params = {**self.extra, **extra_context}
case_parts = []
sql_params = []
default_sql, default_params = compiler.compile(self.default)
for case in self.cases:
try:
case_sql, case_params = compiler.compile(case)
except EmptyResultSet:
continue
except FullResultSet:
default_sql, default_params = compiler.compile(case.result)
break
case_parts.append(case_sql)
sql_params.extend(case_params)
if not case_parts:
return default_sql, default_params
case_joiner = case_joiner or self.case_joiner
template_params["cases"] = case_joiner.join(case_parts)
template_params["default"] = default_sql
sql_params.extend(default_params)
template = template or template_params.get("template", self.template)
sql = template % template_params
if self._output_field_or_none is not None:
sql = connection.ops.unification_cast_sql(self.output_field) % sql
return sql, sql_params
django.db.models.expressions.BaseExpression
Responsible for returning a (sql, [params]) tuple to be included in the current query. Different backends can provide their own implementation, by providing an `as_{vendor}` method and patching the Expression: ``` def override_as_sql(self, compiler, connection): # custom logic return super().as_sql(compiler, connection) setattr(Expression, 'as_' + connection.vendor, override_as_sql) ``` Arguments: * compiler: the query compiler responsible for generating the query. Must have a compile method, returning a (sql, [params]) tuple. Calling compiler(value) will return a quoted `value`. * connection: the database connection used for the current query. Return: (sql, params) Where `sql` is a string containing ordered sql parameters to be replaced with the elements of the list `params`.
def as_sql(self, compiler, connection):
"""
Responsible for returning a (sql, [params]) tuple to be included
in the current query.
Different backends can provide their own implementation, by
providing an `as_{vendor}` method and patching the Expression:
```
def override_as_sql(self, compiler, connection):
# custom logic
return super().as_sql(compiler, connection)
setattr(Expression, 'as_' + connection.vendor, override_as_sql)
```
Arguments:
* compiler: the query compiler responsible for generating the query.
Must have a compile method, returning a (sql, [params]) tuple.
Calling compiler(value) will return a quoted `value`.
* connection: the database connection used for the current query.
Return: (sql, params)
Where `sql` is a string containing ordered sql parameters to be
replaced with the elements of the list `params`.
"""
raise NotImplementedError("Subclasses must implement as_sql()")
def as_sqlite(self, compiler, connection, **extra_context)
django.db.models.expressions.SQLiteNumericMixin
def as_sqlite(self, compiler, connection, **extra_context):
sql, params = self.as_sql(compiler, connection, **extra_context)
try:
if self.output_field.get_internal_type() == "DecimalField":
sql = "(CAST(%s AS NUMERIC))" % sql
except FieldError:
pass
return sql, params
def asc(self, **kwargs)
django.db.models.expressions.BaseExpression
def asc(self, **kwargs):
return OrderBy(self, **kwargs)
def bitand(self, other)
django.db.models.expressions.Combinable
def bitand(self, other):
return self._combine(other, self.BITAND, False)
def bitleftshift(self, other)
django.db.models.expressions.Combinable
def bitleftshift(self, other):
return self._combine(other, self.BITLEFTSHIFT, False)
def bitor(self, other)
django.db.models.expressions.Combinable
def bitor(self, other):
return self._combine(other, self.BITOR, False)
def bitrightshift(self, other)
django.db.models.expressions.Combinable
def bitrightshift(self, other):
return self._combine(other, self.BITRIGHTSHIFT, False)
def bitxor(self, other)
django.db.models.expressions.Combinable
def bitxor(self, other):
return self._combine(other, self.BITXOR, False)
def conditional(self)
django.db.models.expressions.BaseExpression
def contains_aggregate(self)
django.db.models.expressions.BaseExpression
def contains_column_references(self)
django.db.models.expressions.BaseExpression
def contains_over_clause(self)
django.db.models.expressions.BaseExpression
def contains_subquery(self)
django.db.models.expressions.BaseExpression
def convert_value(self)
django.db.models.expressions.BaseExpression
Expressions provide their own converters because users have the option of manually specifying the output_field which may be a different type from the one the database returns.
def copy(self)
django.db.models.expressions.Case
django.db.models.expressions.Case
def copy(self):
c = super().copy()
c.cases = c.cases[:]
return c
django.db.models.expressions.BaseExpression
def copy(self):
return copy.copy(self)
def deconstruct(obj)
django.db.models.expressions.Case
django.db.models.expressions.Case
Return a 3-tuple of class import path, positional arguments, and keyword arguments.
def deconstruct(obj):
"""
Return a 3-tuple of class import path, positional arguments,
and keyword arguments.
"""
# Fallback version
if path and type(obj) is klass:
module_name, _, name = path.rpartition(".")
else:
module_name = obj.__module__
name = obj.__class__.__name__
# Make sure it's actually there and not an inner class
module = import_module(module_name)
if not hasattr(module, name):
raise ValueError(
"Could not find object %s in %s.\n"
"Please note that you cannot serialize things like inner "
"classes. Please move the object into the main module "
"body to use migrations.\n"
"For more information, see "
"https://docs.djangoproject.com/en/%s/topics/migrations/"
"#serializing-values" % (name, module_name, get_docs_version())
)
return (
(
path
if path and type(obj) is klass
else f"{obj.__class__.__module__}.{name}"
),
obj._constructor_args[0],
obj._constructor_args[1],
)
django.db.models.expressions.Expression
Return a 3-tuple of class import path, positional arguments, and keyword arguments.
def deconstruct(obj):
"""
Return a 3-tuple of class import path, positional arguments,
and keyword arguments.
"""
# Fallback version
if path and type(obj) is klass:
module_name, _, name = path.rpartition(".")
else:
module_name = obj.__module__
name = obj.__class__.__name__
# Make sure it's actually there and not an inner class
module = import_module(module_name)
if not hasattr(module, name):
raise ValueError(
"Could not find object %s in %s.\n"
"Please note that you cannot serialize things like inner "
"classes. Please move the object into the main module "
"body to use migrations.\n"
"For more information, see "
"https://docs.djangoproject.com/en/%s/topics/migrations/"
"#serializing-values" % (name, module_name, get_docs_version())
)
return (
(
path
if path and type(obj) is klass
else f"{obj.__class__.__module__}.{name}"
),
obj._constructor_args[0],
obj._constructor_args[1],
)
def desc(self, **kwargs)
django.db.models.expressions.BaseExpression
def desc(self, **kwargs):
return OrderBy(self, descending=True, **kwargs)
def field(self)
django.db.models.expressions.BaseExpression
def flatten(self)
django.db.models.expressions.BaseExpression
Recursively yield this expression and all subexpressions, in depth-first order.
def flatten(self):
"""
Recursively yield this expression and all subexpressions, in
depth-first order.
"""
yield self
for expr in self.get_source_expressions():
if expr:
if hasattr(expr, "flatten"):
yield from expr.flatten()
else:
yield expr
def get_db_converters(self, connection)
django.db.models.expressions.BaseExpression
def get_db_converters(self, connection):
return (
[]
if self.convert_value is self._convert_value_noop
else [self.convert_value]
) + self.output_field.get_db_converters(connection)
def get_group_by_cols(self)
django.db.models.expressions.Case
django.db.models.expressions.Case
def get_group_by_cols(self):
if not self.cases:
return self.default.get_group_by_cols()
return super().get_group_by_cols()
django.db.models.expressions.BaseExpression
def get_group_by_cols(self):
if not self.contains_aggregate:
return [self]
cols = []
for source in self.get_source_expressions():
cols.extend(source.get_group_by_cols())
return cols
def get_lookup(self, lookup)
django.db.models.expressions.BaseExpression
def get_lookup(self, lookup):
return self.output_field.get_lookup(lookup)
def get_refs(self)
django.db.models.expressions.BaseExpression
def get_refs(self):
refs = set()
for expr in self.get_source_expressions():
refs |= expr.get_refs()
return refs
def get_source_expressions(self)
django.db.models.expressions.Case
django.db.models.expressions.Case
def get_source_expressions(self):
return self.cases + [self.default]
django.db.models.expressions.BaseExpression
def get_source_expressions(self):
return []
def get_source_fields(self)
django.db.models.expressions.BaseExpression
Return the underlying field types used by this aggregate.
def get_source_fields(self):
"""Return the underlying field types used by this aggregate."""
return [e._output_field_or_none for e in self.get_source_expressions()]
def get_transform(self, name)
django.db.models.expressions.BaseExpression
def get_transform(self, name):
return self.output_field.get_transform(name)
def identity(self)
django.db.models.expressions.Expression
def output_field(self)
django.db.models.expressions.BaseExpression
Return the output type of this expressions.
def prefix_references(self, prefix)
django.db.models.expressions.BaseExpression
def prefix_references(self, prefix):
clone = self.copy()
clone.set_source_expressions(
[
(
F(f"{prefix}{expr.name}")
if isinstance(expr, F)
else expr.prefix_references(prefix)
)
for expr in self.get_source_expressions()
]
)
return clone
def relabeled_clone(self, change_map)
django.db.models.expressions.BaseExpression
def relabeled_clone(self, change_map):
clone = self.copy()
clone.set_source_expressions(
[
e.relabeled_clone(change_map) if e is not None else None
for e in self.get_source_expressions()
]
)
return clone
def replace_expressions(self, replacements)
django.db.models.expressions.BaseExpression
def replace_expressions(self, replacements):
if replacement := replacements.get(self):
return replacement
clone = self.copy()
source_expressions = clone.get_source_expressions()
clone.set_source_expressions(
[
expr.replace_expressions(replacements) if expr else None
for expr in source_expressions
]
)
return clone
def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False)
django.db.models.expressions.Case
django.db.models.expressions.Case
Provide the chance to do any preprocessing or validation before being added to the query. Arguments: * query: the backend query implementation * allow_joins: boolean allowing or denying use of joins in this query * reuse: a set of reusable joins for multijoins * summarize: a terminal aggregate clause * for_save: whether this expression about to be used in a save or update Return: an Expression to be added to the query.
def resolve_expression(
self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False
):
c = self.copy()
c.is_summary = summarize
for pos, case in enumerate(c.cases):
c.cases[pos] = case.resolve_expression(
query, allow_joins, reuse, summarize, for_save
)
c.default = c.default.resolve_expression(
query, allow_joins, reuse, summarize, for_save
)
return c
django.db.models.expressions.BaseExpression
Provide the chance to do any preprocessing or validation before being added to the query. Arguments: * query: the backend query implementation * allow_joins: boolean allowing or denying use of joins in this query * reuse: a set of reusable joins for multijoins * summarize: a terminal aggregate clause * for_save: whether this expression about to be used in a save or update Return: an Expression to be added to the query.
def resolve_expression(
self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False
):
"""
Provide the chance to do any preprocessing or validation before being
added to the query.
Arguments:
* query: the backend query implementation
* allow_joins: boolean allowing or denying use of joins
in this query
* reuse: a set of reusable joins for multijoins
* summarize: a terminal aggregate clause
* for_save: whether this expression about to be used in a save or update
Return: an Expression to be added to the query.
"""
c = self.copy()
c.is_summary = summarize
c.set_source_expressions(
[
(
expr.resolve_expression(query, allow_joins, reuse, summarize)
if expr
else None
)
for expr in c.get_source_expressions()
]
)
return c
def reverse_ordering(self)
django.db.models.expressions.BaseExpression
def reverse_ordering(self):
return self
def select_format(self, compiler, sql, params)
django.db.models.expressions.BaseExpression
Custom format for select clauses. For example, EXISTS expressions need to be wrapped in CASE WHEN on Oracle.
def select_format(self, compiler, sql, params):
"""
Custom format for select clauses. For example, EXISTS expressions need
to be wrapped in CASE WHEN on Oracle.
"""
if hasattr(self.output_field, "select_format"):
return self.output_field.select_format(compiler, sql, params)
return sql, params
def set_source_expressions(self, exprs)
django.db.models.expressions.Case
django.db.models.expressions.Case
def set_source_expressions(self, exprs):
*self.cases, self.default = exprs
django.db.models.expressions.BaseExpression
def set_source_expressions(self, exprs):
assert not exprs