Lookup API reference
This document has the API references of lookups, the Django API for buildingthe WHERE
clause of a database query. To learn how to use lookups, seeMaking queries; to learn how to create new lookups, see自定义查找.
The lookup API has two components: a RegisterLookupMixin
classthat registers lookups, and the Query Expression API, aset 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 whereall Django builtin lookups are derived:
Lookup
: to lookup a field (e.g. theexact
offield_name__exact
)Transform
: to transform a fieldA lookup expression consists of three parts:Fields part (e.g.
Book.objects.filter(authorbest_friendsfirst_name…
);- Transforms part (may be omitted) (e.g.
lowerfirst3chars__reversed
); - A lookup (e.g.
icontains
) that, if omitted, defaults toexact
.
Registration API
Django uses RegisterLookupMixin
to give a class the interface toregister lookups on itself. The two prominent examples areField
, the base class of all model fields, andAggregate
, the base class of all Django aggregates.
- class
lookups.
RegisterLookupMixin
A mixin that implements the lookup API on a class.
- classmethod
registerlookup
(_lookup, lookup_name=None) Registers a new lookup in the class. For example
DateField.register_lookup(YearExact)
will registerYearExact
lookup onDateField
. It overrides a lookup that already exists withthe same name.lookup_name
will be used for this lookup ifprovided, otherwiselookup.lookup_name
will be used.Returns the
Lookup
namedlookup_name
registered in the class.The default implementation looks recursively on all parent classesand checks if any has a registered lookup namedlookup_name
, returningthe first match.- Returns a
Transform
namedtransform_name
. The defaultimplementation looks recursively on all parent classes to check if anyhas the registered transform namedtransform_name
, returning the firstmatch.
- classmethod
For a class to be a lookup, it must follow the Query Expression API. Lookup
and Transform
naturallyfollow this API.
The Query Expression API
The query expression API is a common set of methods that classes define to beusable in query expressions to translate themselves into SQL expressions. Directfield references, aggregates, and Transform
are examples that follow thisAPI. A class is said to follow the query expression API when it implements thefollowing methods:
assql
(_compiler, connection)- Responsible for producing the query string and parameters for the expression.The
compiler
is anSQLCompiler
object, which has acompile()
method that can be used to compile other expressions. Theconnection
isthe connection used to execute the query.
Calling expression.as_sql()
is usually incorrect - insteadcompiler.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 thatas_vendorname()
methods or subclasses will need to supply data tooverride the generation of the SQL string. See Func.as_sql()
forexample usage.
asvendorname
(_compiler, connection)Works like
as_sql()
method. When an expression is compiled bycompiler.compile()
, Django will first try to callas_vendorname()
,wherevendorname
is the vendor name of the backend used for executingthe query. Thevendorname
is one ofpostgresql
,oracle
,sqlite
, ormysql
for Django's built-in backends.Must return the lookup named
lookup_name
. For instance, by returningself.output_field.get_lookup(lookup_name)
.Must return the lookup named
transform_name
. For instance, by returningself.output_field.get_transform(transform_name)
.- Defines the type of class returned by the
get_lookup()
method. It mustbe aField
instance.
Transform reference
- class
Transform
[source] - A
Transform
is a generic class to implement field transformations. Aprominent example is__year
that transforms aDateField
into aIntegerField
.
The notation to use a Transform
in an lookup expression is<expression><transformation>
(e.g. date
year
).
This class follows the Query Expression API, whichimplies that you can use <expression><transform1><transform2>
. It'sa specialized Func() expression that only acceptsone argument. It can also be used on the right hand side of a filter ordirectly as an annotation.
bilateral
A boolean indicating whether this transformation should apply to both
lhs
andrhs
. Bilateral transformations will be applied torhs
inthe same order as they appear in the lookup expression. By default it is settoFalse
. For example usage, see 自定义查找.The left-hand side - what is being transformed. It must follow theQuery Expression API.
The name of the lookup, used for identifying it on parsing queryexpressions. It cannot contain the string
"__"
.- Defines the class this transformation outputs. It must be a
Field
instance. By default is the same asitslhs.output_field
.
Lookup reference
- class
Lookup
[source] - A
Lookup
is a generic class to implement lookups. A lookup is a queryexpression with a left-hand side,lhs
; a right-hand side,rhs
; and alookup_name
that is used to produce a booleancomparison betweenlhs
andrhs
such aslhs in rhs
orlhs > rhs
.
The notation to use a lookup in an expression is<lhs>__<lookup_name>=<rhs>
.
This class doesn't follow the Query Expression APIsince it has =<rhs>
on its construction: lookups are always the end ofa lookup expression.
lhs
The left-hand side - what is being looked up. The object must followthe Query Expression API.
The right-hand side - what
lhs
is being compared against. It can bea plain value, or something that compiles into SQL, typically anF()
object or aQuerySet
.The name of this lookup, used to identify it on parsing queryexpressions. It cannot contain the string
"__"
.processlhs
(_compiler, connection, lhs=None)[source]- Returns a tuple
(lhs_string, lhs_params)
, as returned bycompiler.compile(lhs)
. This method can be overridden to tune howthelhs
is processed.
compiler
is an SQLCompiler
object, to be used likecompiler.compile(lhs)
for compiling lhs
. The connection
can be used for compiling vendor specific SQL. If lhs
is notNone
, use it as the processed lhs
instead of self.lhs
.
processrhs
(_compiler, connection)[source]- Behaves the same way as
process_lhs()
, for the right-hand side.