django/django

View on GitHub
docs/ref/models/lookups.txt

Summary

Maintainability
Test Coverage
====================
Lookup API reference
====================

.. module:: django.db.models.lookups
   :synopsis: Lookups API

.. currentmodule:: django.db.models

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
:doc:`/topics/db/queries`; to learn how to *create* new lookups, see
:doc:`/howto/custom-lookups`.

The lookup API has two components: a :class:`~lookups.RegisterLookupMixin` class
that registers lookups, and the :ref:`Query Expression API <query-expression>`, 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:

* :class:`Lookup`: to lookup a field (e.g. the ``exact`` of ``field_name__exact``)
* :class:`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``.

.. _lookup-registration-api:

Registration API
================

Django uses :class:`~lookups.RegisterLookupMixin` to give a class the interface to
register lookups on itself or its instances. The two prominent examples are
:class:`~django.db.models.Field`, the base class of all model fields, and
:class:`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 or class instance. For example::

            DateField.register_lookup(YearExact)
            User._meta.get_field("date_joined").register_lookup(MonthExact)

        will register ``YearExact`` lookup on ``DateField`` and ``MonthExact``
        lookup on the ``User.date_joined`` (you can use :ref:`Field Access API
        <model-meta-field-api>` to retrieve a single field instance). It
        overrides a lookup that already exists with the same name. Lookups
        registered on field instances take precedence over the lookups
        registered on classes. ``lookup_name`` will be used for this lookup if
        provided, otherwise ``lookup.lookup_name`` will be used.

    .. method:: get_lookup(lookup_name)

        Returns the :class:`Lookup` named ``lookup_name`` registered in the
        class or class instance depending on what calls it. The default
        implementation looks recursively on all parent classes and checks if
        any has a registered lookup named ``lookup_name``, returning the first
        match. Instance lookups would override any class lookups with the same
        ``lookup_name``.

    .. method:: get_lookups()

        Returns a dictionary of each lookup name registered in the class or
        class instance mapped to the :class:`Lookup` class.

    .. method:: get_transform(transform_name)

        Returns a :class:`Transform` named ``transform_name`` registered in the
        class or class instance. 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 :ref:`Query Expression API
<query-expression>`. :class:`~Lookup` and :class:`~Transform` naturally
follow this API.

.. _query-expression:

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:

.. method:: 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.

    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 :meth:`Func.as_sql` for
    example usage.

.. method:: 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.

.. method:: get_lookup(lookup_name)

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

.. method:: get_transform(transform_name)

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

.. attribute:: output_field

    Defines the type of class returned by the ``get_lookup()`` method. It must
    be a :class:`~django.db.models.Field` instance.

``Transform`` reference
=======================

.. 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 :ref:`Query Expression API <query-expression>`, which
    implies that you can use ``<expression>__<transform1>__<transform2>``. It's
    a specialized :ref:`Func() expression <func-expressions>` that only accepts
    one argument.  It can also be used on the right hand side of a filter or
    directly as an annotation.

    .. attribute:: 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 :doc:`/howto/custom-lookups`.

    .. attribute:: lhs

        The left-hand side - what is being transformed. It must follow the
        :ref:`Query Expression API <query-expression>`.

    .. attribute:: lookup_name

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

    .. attribute:: output_field

        Defines the class this transformation outputs. It must be a
        :class:`~django.db.models.Field` instance. By default is the same as
        its ``lhs.output_field``.

``Lookup`` reference
====================

.. class:: Lookup

    A ``Lookup`` is a generic class to implement lookups. A lookup is a query
    expression with a left-hand side, :attr:`lhs`; a right-hand side,
    :attr:`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 primary notation to use a lookup in an expression is
    ``<lhs>__<lookup_name>=<rhs>``. Lookups can also be used directly in
    ``QuerySet`` filters::

         Book.objects.filter(LessThan(F("word_count"), 7500))

    …or annotations::

         Book.objects.annotate(is_short_story=LessThan(F("word_count"), 7500))

    .. attribute:: lhs

        The left-hand side - what is being looked up. The object typically
        follows the :ref:`Query Expression API <query-expression>`. It may also
        be a plain value.

    .. attribute:: 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``.

    .. attribute:: lookup_name

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

    .. attribute:: prepare_rhs

        Defaults to ``True``. When :attr:`rhs` is a plain value,
        :attr:`prepare_rhs` determines whether it should be prepared for use as
        a parameter in a query. In order to do so,
        ``lhs.output_field.get_prep_value()`` is called if defined, or ``rhs``
        is wrapped in :class:`Value() <django.db.models.Value>` otherwise.

    .. method:: process_lhs(compiler, connection, lhs=None)

        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``.

    .. method:: process_rhs(compiler, connection)

        Behaves the same way as :meth:`process_lhs`, for the right-hand side.