class StartsWith
from django.db.models.lookups import StartsWith
Ancestors (MRO)
- builtins.object
- django.db.models.expressions.Combinable
- django.db.models.expressions.BaseExpression
- django.db.models.expressions.Expression
- django.db.models.lookups.Lookup
- django.db.models.lookups.BuiltinLookup
- django.db.models.lookups.PatternLookup
- django.db.models.lookups.StartsWith
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 |
can_use_none_as_rhs |
False |
django.db.models.lookups.Lookup |
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 |
lookup_name |
startswith |
django.db.models.lookups.StartsWith |
lookup_name |
None |
django.db.models.lookups.Lookup |
param_pattern |
%s%% |
django.db.models.lookups.StartsWith |
param_pattern |
%%%s%% |
django.db.models.lookups.PatternLookup |
prepare_rhs |
False |
django.db.models.lookups.PatternLookup |
prepare_rhs |
True |
django.db.models.lookups.Lookup |
window_compatible |
False |
django.db.models.expressions.BaseExpression |
def allowed_default(self)
django.db.models.lookups.Lookup
def apply_bilateral_transforms(self, value)
django.db.models.lookups.Lookup
def apply_bilateral_transforms(self, value):
for transform in self.bilateral_transforms:
value = transform(value)
return value
def as_oracle(self, compiler, connection)
django.db.models.lookups.Lookup
def as_oracle(self, compiler, connection):
# Oracle doesn't allow EXISTS() and filters to be compared to another
# expression unless they're wrapped in a CASE WHEN.
wrapped = False
exprs = []
for expr in (self.lhs, self.rhs):
if connection.ops.conditional_expression_supported_in_where_clause(expr):
expr = Case(When(expr, then=True), default=False)
wrapped = True
exprs.append(expr)
lookup = type(self)(*exprs) if wrapped else self
return lookup.as_sql(compiler, connection)
def as_sql(self, compiler, connection)
django.db.models.lookups.BuiltinLookup
django.db.models.lookups.BuiltinLookup
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):
lhs_sql, params = self.process_lhs(compiler, connection)
rhs_sql, rhs_params = self.process_rhs(compiler, connection)
params.extend(rhs_params)
rhs_sql = self.get_rhs_op(connection, rhs_sql)
return "%s %s" % (lhs_sql, rhs_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 asc(self, **kwargs)
django.db.models.expressions.BaseExpression
def asc(self, **kwargs):
return OrderBy(self, **kwargs)
def batch_process_rhs(self, compiler, connection, rhs=None)
django.db.models.lookups.Lookup
def batch_process_rhs(self, compiler, connection, rhs=None):
if rhs is None:
rhs = self.rhs
if self.bilateral_transforms:
sqls, sqls_params = [], []
for p in rhs:
value = Value(p, output_field=self.lhs.output_field)
value = self.apply_bilateral_transforms(value)
value = value.resolve_expression(compiler.query)
sql, sql_params = compiler.compile(value)
sqls.append(sql)
sqls_params.extend(sql_params)
else:
_, params = self.get_db_prep_lookup(rhs, connection)
sqls, sqls_params = ["%s"] * len(params), params
return sqls, sqls_params
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.BaseExpression
def copy(self):
return copy.copy(self)
def deconstruct(obj)
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_db_prep_lookup(self, value, connection)
django.db.models.lookups.Lookup
def get_db_prep_lookup(self, value, connection):
return ("%s", [value])
def get_group_by_cols(self)
django.db.models.lookups.Lookup
django.db.models.lookups.Lookup
def get_group_by_cols(self):
cols = []
for source in self.get_source_expressions():
cols.extend(source.get_group_by_cols())
return 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_prep_lhs(self)
django.db.models.lookups.Lookup
def get_prep_lhs(self):
if hasattr(self.lhs, "resolve_expression"):
return self.lhs
return Value(self.lhs)
def get_prep_lookup(self)
django.db.models.lookups.Lookup
def get_prep_lookup(self):
if not self.prepare_rhs or hasattr(self.rhs, "resolve_expression"):
return self.rhs
if hasattr(self.lhs, "output_field"):
if hasattr(self.lhs.output_field, "get_prep_value"):
return self.lhs.output_field.get_prep_value(self.rhs)
elif self.rhs_is_direct_value():
return Value(self.rhs)
return self.rhs
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_rhs_op(self, connection, rhs)
django.db.models.lookups.PatternLookup
django.db.models.lookups.PatternLookup
def get_rhs_op(self, connection, rhs):
# Assume we are in startswith. We need to produce SQL like:
# col LIKE %s, ['thevalue%']
# For python values we can (and should) do that directly in Python,
# but if the value is for example reference to other column, then
# we need to add the % pattern match to the lookup by something like
# col LIKE othercol || '%%'
# So, for Python values we don't need any special pattern, but for
# SQL reference values or SQL transformations we need the correct
# pattern added.
if hasattr(self.rhs, "as_sql") or self.bilateral_transforms:
pattern = connection.pattern_ops[self.lookup_name].format(
connection.pattern_esc
)
return pattern.format(rhs)
else:
return super().get_rhs_op(connection, rhs)
django.db.models.lookups.BuiltinLookup
def get_rhs_op(self, connection, rhs):
return connection.operators[self.lookup_name] % rhs
def get_source_expressions(self)
django.db.models.lookups.Lookup
django.db.models.lookups.Lookup
def get_source_expressions(self):
if self.rhs_is_direct_value():
return [self.lhs]
return [self.lhs, self.rhs]
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.lookups.Lookup
django.db.models.lookups.Lookup
django.db.models.expressions.Expression
def output_field(self)
django.db.models.lookups.Lookup
django.db.models.lookups.Lookup
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 process_lhs(self, compiler, connection, lhs=None)
django.db.models.lookups.BuiltinLookup
django.db.models.lookups.BuiltinLookup
def process_lhs(self, compiler, connection, lhs=None):
lhs_sql, params = super().process_lhs(compiler, connection, lhs)
field_internal_type = self.lhs.output_field.get_internal_type()
if (
hasattr(connection.ops.__class__, "field_cast_sql")
and connection.ops.__class__.field_cast_sql
is not BaseDatabaseOperations.field_cast_sql
):
warnings.warn(
(
"The usage of DatabaseOperations.field_cast_sql() is deprecated. "
"Implement DatabaseOperations.lookup_cast() instead."
),
RemovedInDjango60Warning,
)
db_type = self.lhs.output_field.db_type(connection=connection)
lhs_sql = (
connection.ops.field_cast_sql(db_type, field_internal_type) % lhs_sql
)
lhs_sql = (
connection.ops.lookup_cast(self.lookup_name, field_internal_type) % lhs_sql
)
return lhs_sql, list(params)
django.db.models.lookups.Lookup
def process_lhs(self, compiler, connection, lhs=None):
lhs = lhs or self.lhs
if hasattr(lhs, "resolve_expression"):
lhs = lhs.resolve_expression(compiler.query)
sql, params = compiler.compile(lhs)
if isinstance(lhs, Lookup):
# Wrapped in parentheses to respect operator precedence.
sql = f"({sql})"
return sql, params
def process_rhs(self, qn, connection)
django.db.models.lookups.PatternLookup
django.db.models.lookups.PatternLookup
def process_rhs(self, qn, connection):
rhs, params = super().process_rhs(qn, connection)
if self.rhs_is_direct_value() and params and not self.bilateral_transforms:
params[0] = self.param_pattern % connection.ops.prep_for_like_query(
params[0]
)
return rhs, params
django.db.models.lookups.Lookup
def process_rhs(self, compiler, connection):
value = self.rhs
if self.bilateral_transforms:
if self.rhs_is_direct_value():
# Do not call get_db_prep_lookup here as the value will be
# transformed before being used for lookup
value = Value(value, output_field=self.lhs.output_field)
value = self.apply_bilateral_transforms(value)
value = value.resolve_expression(compiler.query)
if hasattr(value, "as_sql"):
sql, params = compiler.compile(value)
# Ensure expression is wrapped in parentheses to respect operator
# precedence but avoid double wrapping as it can be misinterpreted
# on some backends (e.g. subqueries on SQLite).
if sql and sql[0] != "(":
sql = "(%s)" % sql
return sql, params
else:
return self.get_db_prep_lookup(value, connection)
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.lookups.Lookup
django.db.models.lookups.Lookup
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
c.lhs = self.lhs.resolve_expression(
query, allow_joins, reuse, summarize, for_save
)
if hasattr(self.rhs, "resolve_expression"):
c.rhs = self.rhs.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 rhs_is_direct_value(self)
django.db.models.lookups.Lookup
def rhs_is_direct_value(self):
return not hasattr(self.rhs, "as_sql")
def select_format(self, compiler, sql, params)
django.db.models.lookups.Lookup
django.db.models.lookups.Lookup
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):
# Wrap filters with a CASE WHEN expression if a database backend
# (e.g. Oracle) doesn't support boolean expression in SELECT or GROUP
# BY list.
if not compiler.connection.features.supports_boolean_expr_in_select_clause:
sql = f"CASE WHEN {sql} THEN 1 ELSE 0 END"
return 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, new_exprs)
django.db.models.lookups.Lookup
django.db.models.lookups.Lookup
def set_source_expressions(self, new_exprs):
if len(new_exprs) == 1:
self.lhs = new_exprs[0]
else:
self.lhs, self.rhs = new_exprs
django.db.models.expressions.BaseExpression
def set_source_expressions(self, exprs):
assert not exprs