Django2.0手册:Lookup API reference



This document has the API references of lookups, the Django API for building
the WHERE clause of a database query. To learn how to use lookups, see
Making queries; to learn how to create new lookups, see
自定义查找.

The lookup API has two components: a RegisterLookupMixin class
that registers lookups, and the Query Expression API, a
set of methods that a class has to implement to be registrable as a lookup.

Django has two base classes that follow the query expression API and from where
all Django builtin lookups are derived:

  • Lookup: to lookup a field (e.g. the exact of field_name__exact)
  • Transform: to transform a field

A lookup expression consists of three parts:

  • Fields part (e.g. Book.objects.filter(author__best_friends__first_name...);
  • Transforms part (may be omitted) (e.g. __lower__first3chars__reversed);
  • A lookup (e.g. __icontains) that, if omitted, defaults to __exact.

Registration API¶

Django uses RegisterLookupMixin to give a class the interface to
register lookups on itself. The two prominent examples are
Field, the base class of all model fields, and
Aggregate, the base class of all Django aggregates.

class lookups.RegisterLookupMixin

A mixin that implements the lookup API on a class.

classmethod register_lookup(lookup, lookup_name=None)

Registers a new lookup in the class. For example
DateField.register_lookup(YearExact) will register YearExact
lookup on DateField. It overrides a lookup that already exists with
the same name. lookup_name will be used for this lookup if
provided, otherwise lookup.lookup_name will be used.

get_lookup(lookup_name)

Returns the Lookup named lookup_name registered in the class.
The default implementation looks recursively on all parent classes
and checks if any has a registered lookup named lookup_name, returning
the first match.

get_transform(transform_name)

Returns a Transform named transform_name. The default
implementation looks recursively on all parent classes to check if any
has the registered transform named transform_name, returning the first
match.

For a class to be a lookup, it must follow the Query Expression API. Lookup and Transform naturally
follow this API.

The Query Expression API¶

The query expression API is a common set of methods that classes define to be
usable in query expressions to translate themselves into SQL expressions. Direct
field references, aggregates, and Transform are examples that follow this
API. A class is said to follow the query expression API when it implements the
following methods:

as_sql(compiler, connection)

Responsible for producing the query string and parameters for the expression.
The compiler is an SQLCompiler object, which has a compile()
method that can be used to compile other expressions. The connection is
the connection used to execute the query.

Calling expression.as_sql() is usually incorrect – instead
compiler.compile(expression) should be used. The compiler.compile()
method will take care of calling vendor-specific methods of the expression.

Custom keyword arguments may be defined on this method if it’s likely that
as_vendorname() methods or subclasses will need to supply data to
override the generation of the SQL string. See Func.as_sql() for
example usage.

as_vendorname(compiler, connection)

Works like as_sql() method. When an expression is compiled by
compiler.compile(), Django will first try to call as_vendorname(),
where vendorname is the vendor name of the backend used for executing
the query. The vendorname is one of postgresql, oracle,
sqlite, or mysql for Django’s built-in backends.

get_lookup(lookup_name)

Must return the lookup named lookup_name. For instance, by returning
self.output_field.get_lookup(lookup_name).

get_transform(transform_name)

Must return the lookup named transform_name. For instance, by returning
self.output_field.get_transform(transform_name).

output_field

Defines the type of class returned by the get_lookup() method. It must
be a Field instance.

Transform reference¶

class Transform[source]

A Transform is a generic class to implement field transformations. A
prominent example is __year that transforms a DateField into a
IntegerField.

The notation to use a Transform in an lookup expression is
<expression>__<transformation> (e.g. date__year).

This class follows the Query Expression API, which
implies that you can use <expression>__<transform1>__<transform2>. It’s
a specialized Func() expression that only accepts
one argument. It can also be used on the right hand side of a filter or
directly as an annotation.

bilateral

A boolean indicating whether this transformation should apply to both
lhs and rhs. Bilateral transformations will be applied to rhs in
the same order as they appear in the lookup expression. By default it is set
to False. For example usage, see 自定义查找.

lhs

The left-hand side – what is being transformed. It must follow the
Query Expression API.

lookup_name

The name of the lookup, used for identifying it on parsing query
expressions. It cannot contain the string "__".

output_field

Defines the class this transformation outputs. It must be a
Field instance. By default is the same as
its lhs.output_field.

Lookup reference¶

class Lookup[source]

A Lookup is a generic class to implement lookups. A lookup is a query
expression with a left-hand side, lhs; a right-hand side,
rhs; and a lookup_name that is used to produce a boolean
comparison between lhs and rhs such as lhs in rhs or
lhs > rhs.

The notation to use a lookup in an expression is
<lhs>__<lookup_name>=<rhs>.

This class doesn’t follow the Query Expression API
since it has =<rhs> on its construction: lookups are always the end of
a lookup expression.

lhs

The left-hand side – what is being looked up. The object must follow
the Query Expression API.

rhs

The right-hand side – what lhs is being compared against. It can be
a plain value, or something that compiles into SQL, typically an
F() object or a QuerySet.

lookup_name

The name of this lookup, used to identify it on parsing query
expressions. It cannot contain the string "__".

process_lhs(compiler, connection, lhs=None)[source]

Returns a tuple (lhs_string, lhs_params), as returned by
compiler.compile(lhs). This method can be overridden to tune how
the lhs is processed.

compiler is an SQLCompiler object, to be used like
compiler.compile(lhs) for compiling lhs. The connection
can be used for compiling vendor specific SQL. If lhs is not
None, use it as the processed lhs instead of self.lhs.

process_rhs(compiler, connection)[source]

Behaves the same way as process_lhs(), for the right-hand side.