summaryrefslogtreecommitdiff
path: root/docs/ref/models/lookups.txt
diff options
context:
space:
mode:
Diffstat (limited to 'docs/ref/models/lookups.txt')
-rw-r--r--docs/ref/models/lookups.txt207
1 files changed, 207 insertions, 0 deletions
diff --git a/docs/ref/models/lookups.txt b/docs/ref/models/lookups.txt
new file mode 100644
index 0000000000..ef331aa0ab
--- /dev/null
+++ b/docs/ref/models/lookups.txt
@@ -0,0 +1,207 @@
+====================
+Lookup API reference
+====================
+
+.. module:: django.db.models.lookups
+ :synopsis: Lookups API
+
+.. currentmodule:: django.db.models
+
+.. versionadded:: 1.7
+
+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 `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)
+
+ 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.
+
+ .. 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 `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, qn, connection)
+
+ Responsible for producing the query string and parameters for the expression.
+ The ``qn`` 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
+ ``qn.compile(expression)`` should be used. The ``qn.compile()`` method will
+ take care of calling vendor-specific methods of the expression.
+
+.. method:: as_vendorname(self, qn, connection)
+
+ Works like ``as_sql()`` method. When an expression is compiled by
+ ``qn.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 `Query Expression API <query-expression>`_, which
+ implies that you can use ``<expression>__<transform1>__<transform2>``.
+
+ .. attribute:: lhs
+
+ The left-hand side - what is being transformed. It must follow the
+ `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``.
+
+ .. method:: as_sql
+
+ To be overridden; raises :exc:`NotImplementedError`.
+
+ .. method:: get_lookup(lookup_name)
+
+ Same as :meth:`~lookups.RegisterLookupMixin.get_lookup()`.
+
+ .. method:: get_transform(transform_name)
+
+ Same as :meth:`~lookups.RegisterLookupMixin.get_transform()`.
+
+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 `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 `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(qn, connection[, lhs=None])
+
+ Returns a tuple ``(lhs_string, lhs_params)``, as returned by
+ ``qn.compile(lhs)``. This method can be overridden to tune how the
+ ``lhs`` is processed.
+
+ ``qn`` is an ``SQLCompiler`` object, to be used like ``qn.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(qn, connection)
+
+ Behaves the same way as :meth:`process_lhs`, for the right-hand side.