summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Tamlyn <marc.tamlyn@gmail.com>2014-10-09 17:04:50 +0100
committerMarc Tamlyn <marc.tamlyn@gmail.com>2014-10-09 18:44:58 +0100
commit92a17eaae081a213171b044858d6fc29df2df733 (patch)
treeeae95057cfb26745d2bd99dba63811aae6d5db8e
parentd6a87eefd87250e68457488cfd62fb2cc8211b24 (diff)
Fixed #23627 -- Allowed register_lookup to work as a decorator.
-rw-r--r--django/contrib/postgres/fields/array.py16
-rw-r--r--django/db/models/lookups.py1
-rw-r--r--docs/howto/custom-lookups.txt12
-rw-r--r--docs/releases/1.8.txt3
-rw-r--r--tests/custom_lookups/tests.py4
5 files changed, 22 insertions, 14 deletions
diff --git a/django/contrib/postgres/fields/array.py b/django/contrib/postgres/fields/array.py
index dea9c0440d..1a969d7c0e 100644
--- a/django/contrib/postgres/fields/array.py
+++ b/django/contrib/postgres/fields/array.py
@@ -160,6 +160,7 @@ class ArrayField(Field):
return super(ArrayField, self).formfield(**defaults)
+@ArrayField.register_lookup
class ArrayContainsLookup(Lookup):
lookup_name = 'contains'
@@ -171,9 +172,7 @@ class ArrayContainsLookup(Lookup):
return '%s @> %s::%s' % (lhs, rhs, type_cast), params
-ArrayField.register_lookup(ArrayContainsLookup)
-
-
+@ArrayField.register_lookup
class ArrayContainedByLookup(Lookup):
lookup_name = 'contained_by'
@@ -184,9 +183,7 @@ class ArrayContainedByLookup(Lookup):
return '%s <@ %s' % (lhs, rhs), params
-ArrayField.register_lookup(ArrayContainedByLookup)
-
-
+@ArrayField.register_lookup
class ArrayOverlapLookup(Lookup):
lookup_name = 'overlap'
@@ -197,9 +194,7 @@ class ArrayOverlapLookup(Lookup):
return '%s && %s' % (lhs, rhs), params
-ArrayField.register_lookup(ArrayOverlapLookup)
-
-
+@ArrayField.register_lookup
class ArrayLenTransform(Transform):
lookup_name = 'len'
@@ -212,9 +207,6 @@ class ArrayLenTransform(Transform):
return 'array_length(%s, 1)' % lhs, params
-ArrayField.register_lookup(ArrayLenTransform)
-
-
class IndexTransform(Transform):
def __init__(self, index, base_field, *args, **kwargs):
diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py
index 8242602e82..66bdde54b4 100644
--- a/django/db/models/lookups.py
+++ b/django/db/models/lookups.py
@@ -45,6 +45,7 @@ class RegisterLookupMixin(object):
if 'class_lookups' not in cls.__dict__:
cls.class_lookups = {}
cls.class_lookups[lookup.lookup_name] = lookup
+ return lookup
@classmethod
def _unregister_lookup(cls, lookup):
diff --git a/docs/howto/custom-lookups.txt b/docs/howto/custom-lookups.txt
index c02b896071..820a2ef574 100644
--- a/docs/howto/custom-lookups.txt
+++ b/docs/howto/custom-lookups.txt
@@ -46,6 +46,18 @@ it with ``Field`` directly::
from django.db.models.fields import Field
Field.register_lookup(NotEqual)
+Lookup registration can also be done using a decorator pattern::
+
+ from django.db.models.fields import Field
+
+ @Field.registerLookup
+ class NotEqualLookup(Lookup):
+ # ...
+
+.. versionchanged:: 1.8
+
+ The ability to use the decorator pattern was added.
+
We can now use ``foo__ne`` for any field ``foo``. You will need to ensure that
this registration happens before you try to create any querysets using it. You
could place the implementation in a ``models.py`` file, or register the lookup
diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt
index 0e42f1f12f..631b0bd2f0 100644
--- a/docs/releases/1.8.txt
+++ b/docs/releases/1.8.txt
@@ -299,6 +299,9 @@ Models
* ``extra(select={...})`` now allows you to escape a literal ``%s`` sequence
using ``%%s``.
+* :doc:`Custom Lookups</howto/custom-lookups>` can now be registered using
+ a decorator pattern.
+
Signals
^^^^^^^
diff --git a/tests/custom_lookups/tests.py b/tests/custom_lookups/tests.py
index c89b268f6e..a965e5a4e8 100644
--- a/tests/custom_lookups/tests.py
+++ b/tests/custom_lookups/tests.py
@@ -50,6 +50,7 @@ class YearTransform(models.Transform):
return models.IntegerField()
+@YearTransform.register_lookup
class YearExact(models.lookups.Lookup):
lookup_name = 'exact'
@@ -66,9 +67,9 @@ class YearExact(models.lookups.Lookup):
return ("%(lhs)s >= (%(rhs)s || '-01-01')::date "
"AND %(lhs)s <= (%(rhs)s || '-12-31')::date" %
{'lhs': lhs_sql, 'rhs': rhs_sql}, params)
-YearTransform.register_lookup(YearExact)
+@YearTransform.register_lookup
class YearLte(models.lookups.LessThanOrEqual):
"""
The purpose of this lookup is to efficiently compare the year of the field.
@@ -86,7 +87,6 @@ class YearLte(models.lookups.LessThanOrEqual):
# WHERE somecol <= '2013-12-31')
# but also make it work if the rhs_sql is field reference.
return "%s <= (%s || '-12-31')::date" % (lhs_sql, rhs_sql), params
-YearTransform.register_lookup(YearLte)
class SQLFunc(models.Lookup):