summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Tamlyn <marc.tamlyn@gmail.com>2015-05-30 21:22:36 +0100
committerMarc Tamlyn <marc.tamlyn@gmail.com>2015-05-30 21:39:45 +0100
commit74fe4428e51030cbed768083489f0497f4453c17 (patch)
treec5e4c483897bb0ab6f4a61b287329e84fbbbfcc8
parent38eacbde62cd83ffaa64db7719c2c643f69551e0 (diff)
Add HasAnyKeys lookup for HStoreField.
-rw-r--r--django/contrib/postgres/fields/hstore.py15
-rw-r--r--django/contrib/postgres/lookups.py15
-rw-r--r--docs/ref/contrib/postgres/fields.txt17
-rw-r--r--tests/postgres_tests/test_hstore.py6
4 files changed, 41 insertions, 12 deletions
diff --git a/django/contrib/postgres/fields/hstore.py b/django/contrib/postgres/fields/hstore.py
index b8e47edf17..c87eef3bef 100644
--- a/django/contrib/postgres/fields/hstore.py
+++ b/django/contrib/postgres/fields/hstore.py
@@ -55,18 +55,9 @@ class HStoreField(Field):
HStoreField.register_lookup(lookups.DataContains)
HStoreField.register_lookup(lookups.ContainedBy)
-
-
-@HStoreField.register_lookup
-class HasKeyLookup(lookups.PostgresSimpleLookup):
- lookup_name = 'has_key'
- operator = '?'
-
-
-@HStoreField.register_lookup
-class HasKeysLookup(lookups.PostgresSimpleLookup):
- lookup_name = 'has_keys'
- operator = '?&'
+HStoreField.register_lookup(lookups.HasKey)
+HStoreField.register_lookup(lookups.HasKeys)
+HStoreField.register_lookup(lookups.HasAnyKeys)
class KeyTransform(Transform):
diff --git a/django/contrib/postgres/lookups.py b/django/contrib/postgres/lookups.py
index eb7cfd8359..887337861a 100644
--- a/django/contrib/postgres/lookups.py
+++ b/django/contrib/postgres/lookups.py
@@ -30,6 +30,21 @@ class Overlap(PostgresSimpleLookup):
operator = '&&'
+class HasKey(PostgresSimpleLookup):
+ lookup_name = 'has_key'
+ operator = '?'
+
+
+class HasKeys(PostgresSimpleLookup):
+ lookup_name = 'has_keys'
+ operator = '?&'
+
+
+class HasAnyKeys(PostgresSimpleLookup):
+ lookup_name = 'has_any_keys'
+ operator = '?|'
+
+
class Unaccent(FunctionTransform):
bilateral = True
lookup_name = 'unaccent'
diff --git a/docs/ref/contrib/postgres/fields.txt b/docs/ref/contrib/postgres/fields.txt
index 235dbc9079..5313ac4092 100644
--- a/docs/ref/contrib/postgres/fields.txt
+++ b/docs/ref/contrib/postgres/fields.txt
@@ -385,6 +385,23 @@ Returns objects where the given key is in the data. Uses the SQL operator
>>> Dog.objects.filter(data__has_key='owner')
[<Dog: Meg>]
+.. fieldlookup:: hstorefield.has_any_keys
+
+has_any_keys
+~~~~~~~~~~~~
+
+.. versionadded:: 1.9
+
+Returns objects where any of the given keys are in the data. Uses the SQL
+operator ``?|``. For example::
+
+ >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
+ >>> Dog.objects.create(name='Meg', data={'owner': 'Bob'})
+ >>> Dog.objects.create(name='Fred', data={})
+
+ >>> Dog.objects.filter(data__has_any_keys=['owner', 'breed'])
+ [<Dog: Rufus>, <Dog: Meg>]
+
.. fieldlookup:: hstorefield.has_keys
has_keys
diff --git a/tests/postgres_tests/test_hstore.py b/tests/postgres_tests/test_hstore.py
index 470ede9d22..50a4702716 100644
--- a/tests/postgres_tests/test_hstore.py
+++ b/tests/postgres_tests/test_hstore.py
@@ -79,6 +79,12 @@ class TestQuerying(PostgresSQLTestCase):
self.objs[1:2]
)
+ def test_has_any_keys(self):
+ self.assertSequenceEqual(
+ HStoreModel.objects.filter(field__has_any_keys=['a', 'c']),
+ self.objs[:3]
+ )
+
def test_key_transform(self):
self.assertSequenceEqual(
HStoreModel.objects.filter(field__a='b'),