diff options
| author | Thomas Chaumeny <t.chaumeny@gmail.com> | 2014-09-14 12:34:41 +0200 |
|---|---|---|
| committer | Anssi Kääriäinen <akaariai@gmail.com> | 2014-10-28 10:02:10 +0200 |
| commit | 00aa562884a418c4ee20e223ab82c3455997ee7d (patch) | |
| tree | 934393c39e5087bad689217003a1de59484e0000 /docs | |
| parent | 6b39401bafa955f4891700996aa666349fcdef74 (diff) | |
Fixed #23493 -- Added bilateral attribute to Transform
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/howto/custom-lookups.txt | 48 | ||||
| -rw-r--r-- | docs/ref/models/lookups.txt | 9 | ||||
| -rw-r--r-- | docs/releases/1.8.txt | 5 |
3 files changed, 57 insertions, 5 deletions
diff --git a/docs/howto/custom-lookups.txt b/docs/howto/custom-lookups.txt index 820a2ef574..d3ed726ba3 100644 --- a/docs/howto/custom-lookups.txt +++ b/docs/howto/custom-lookups.txt @@ -127,7 +127,7 @@ function ``ABS()`` to transform the value before comparison:: lhs, params = qn.compile(self.lhs) return "ABS(%s)" % lhs, params -Next, lets register it for ``IntegerField``:: +Next, let's register it for ``IntegerField``:: from django.db.models import IntegerField IntegerField.register_lookup(AbsoluteValue) @@ -144,9 +144,7 @@ SQL:: SELECT ... WHERE ABS("experiments"."change") < 27 -Subclasses of ``Transform`` usually only operate on the left-hand side of the -expression. Further lookups will work on the transformed value. Note that in -this case where there is no other lookup specified, Django interprets +Note that in case there is no other lookup specified, Django interprets ``change__abs=27`` as ``change__abs__exact=27``. When looking for which lookups are allowable after the ``Transform`` has been @@ -197,7 +195,7 @@ Notice also that as both sides are used multiple times in the query the params need to contain ``lhs_params`` and ``rhs_params`` multiple times. The final query does the inversion (``27`` to ``-27``) directly in the -database. The reason for doing this is that if the self.rhs is something else +database. The reason for doing this is that if the ``self.rhs`` is something else than a plain integer value (for example an ``F()`` reference) we can't do the transformations in Python. @@ -208,6 +206,46 @@ transformations in Python. want to add an index on ``abs(change)`` which would allow these queries to be very efficient. +A bilateral transformer example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``AbsoluteValue`` example we discussed previously is a transformation which +applies to the left-hand side of the lookup. There may be some cases where you +want the transformation to be applied to both the left-hand side and the +right-hand side. For instance, if you want to filter a queryset based on the +equality of the left and right-hand side insensitively to some SQL function. + +Let's examine the simple example of case-insensitive transformation here. This +transformation isn't very useful in practice as Django already comes with a bunch +of built-in case-insensitive lookups, but it will be a nice demonstration of +bilateral transformations in a database-agnostic way. + +We define an ``UpperCase`` transformer which uses the SQL function ``UPPER()`` to +transform the values before comparison. We define +:attr:`bilateral = True <django.db.models.Transform.bilateral>` to indicate that +this transformation should apply to both ``lhs`` and ``rhs``:: + + from django.db.models import Transform + + class UpperCase(Transform): + lookup_name = 'upper' + bilateral = True + + def as_sql(self, qn, connection): + lhs, params = qn.compile(self.lhs) + return "UPPER(%s)" % lhs, params + +Next, let's register it:: + + from django.db.models import CharField, TextField + CharField.register_lookup(UpperCase) + TextField.register_lookup(UpperCase) + +Now, the queryset ``Author.objects.filter(name__upper="doe")`` will generate a case +insensitive query like this:: + + SELECT ... WHERE UPPER("author"."name") = UPPER('doe') + Writing alternative implementations for existing lookups ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/ref/models/lookups.txt b/docs/ref/models/lookups.txt index d3f64c07a9..da338b7cb2 100644 --- a/docs/ref/models/lookups.txt +++ b/docs/ref/models/lookups.txt @@ -129,6 +129,15 @@ Transform reference This class follows the :ref:`Query Expression API <query-expression>`, which implies that you can use ``<expression>__<transform1>__<transform2>``. + .. attribute:: bilateral + + .. versionadded:: 1.8 + + 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 diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 6b08e2b5a1..e5d3282874 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -306,6 +306,11 @@ Models * :doc:`Custom Lookups</howto/custom-lookups>` can now be registered using a decorator pattern. +* The new :attr:`Transform.bilateral <django.db.models.Transform.bilateral>` + attribute allows creating bilateral transformations. These transformations + are applied to both ``lhs`` and ``rhs`` when used in a lookup expression, + providing opportunities for more sophisticated lookups. + Signals ^^^^^^^ |
