Lookup API reference
The lookup API has two components: a RegisterLookupMixin class that registers lookups, and the , 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
offield_name__exact
) - : to transform a field
A lookup expression consists of three parts:
- Fields part (e.g.
Book.objects.filter(author__best_friends__first_name...
); - A lookup (e.g.
__icontains
) that, if omitted, defaults to__exact
.
Django uses RegisterLookupMixin to give a class the interface to register lookups on itself. The two prominent examples are , the base class of all model fields, and Transform, the base class of all Django transforms.
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 registerYearExact
lookup onDateField
. It overrides a lookup that already exists with the same name.lookup_name
will be used for this lookup if provided, otherwiselookup.lookup_name
will be used.get_lookup
(lookup_name)Returns the named
lookup_name
registered in the class. The default implementation looks recursively on all parent classes and checks if any has a registered lookup namedlookup_name
, returning the first match.get_lookups
()Returns a dictionary of each lookup name registered in the class mapped to the Lookup class.
get_transform
(transform_name)Returns a named
transform_name
. The default implementation looks recursively on all parent classes to check if any has the registered transform namedtransform_name
, returning the first match.
For a class to be a lookup, it must follow the Query Expression API. and Transform naturally follow this 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)
Generates the SQL fragment for the expression. Returns a tuple (sql, params)
, where sql
is the SQL string, and params
is the list or tuple of query parameters. 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.
Custom keyword arguments may be defined on this method if it’s likely that methods or subclasses will need to supply data to override the generation of the SQL string. See 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.
class Transform
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 a lookup expression is <expression>__<transformation>
(e.g. date__year
).
This class follows the , 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
andrhs
. Bilateral transformations will be applied torhs
in the same order as they appear in the lookup expression. By default it is set toFalse
. For example usage, see .lhs
The left-hand side - what is being transformed. It must follow the Query Expression API.
output_field
Defines the class this transformation outputs. It must be a instance. By default is the same as its
lhs.output_field
.
class Lookup
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, ; 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 primary notation to use a lookup in an expression is <lhs>__<lookup_name>=<rhs>
. Lookups can also be used directly in QuerySet
filters:
…or annotations:
Book.objects.annotate(is_short_story=LessThan(F('word_count'), 7500))
lhs
The left-hand side - what is being looked up. The object typically follows the Query Expression API. It may also be a plain value.
rhs
The right-hand side - what
lhs
is being compared against. It can be a plain value, or something that compiles into SQL, typically anF()
object or aQuerySet
.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)Returns a tuple
(lhs_string, lhs_params)
, as returned bycompiler.compile(lhs)
. This method can be overridden to tune how thelhs
is processed.compiler
is anSQLCompiler
object, to be used likecompiler.compile(lhs)
for compilinglhs
. Theconnection
can be used for compiling vendor specific SQL. Iflhs
is notNone
, use it as the processedlhs
instead ofself.lhs
.(compiler, connection)
Behaves the same way as , for the right-hand side.
Changed in Django 4.0: