Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/docs/ref/models/lookups.txt
blob: eae0d2a5b3aaaeb1ad551f512b559d19f5b3398f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
====================
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. The two prominent examples are
:class:`~django.db.models.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.

        .. versionchanged:: 1.9

            The ``lookup_name`` parameter was added.

    .. method:: get_lookup(lookup_name)

        Returns the :class:`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.

    .. method:: get_transform(transform_name)

        Returns a :class:`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 :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(self, 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.

.. method:: as_vendorname(self, 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 an 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.

    .. versionchanged:: 1.9

        ``Transform`` is now a subclass of ``Func``.

    .. 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 notation to use a lookup in an expression is
    ``<lhs>__<lookup_name>=<rhs>``.

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

    .. attribute:: lhs

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

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

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