summaryrefslogtreecommitdiff
path: root/django/contrib/postgres/validators.py
diff options
context:
space:
mode:
authorMarc Tamlyn <marc.tamlyn@gmail.com>2014-03-14 17:34:49 +0000
committerMarc Tamlyn <marc.tamlyn@gmail.com>2014-11-04 09:26:40 +0000
commit36f514f06553ef299001b4e9a5f63ec806a50581 (patch)
tree966c1b958c49cd266f76c385acb0a2bd330f7c10 /django/contrib/postgres/validators.py
parent5c517ec21839358249c6f17611abbf84661fb200 (diff)
Added HStoreField.
Thanks to `django-hstore` for inspiration in some areas, and many people for reviews.
Diffstat (limited to 'django/contrib/postgres/validators.py')
-rw-r--r--django/contrib/postgres/validators.py51
1 files changed, 50 insertions, 1 deletions
diff --git a/django/contrib/postgres/validators.py b/django/contrib/postgres/validators.py
index 353305949e..19d0a69765 100644
--- a/django/contrib/postgres/validators.py
+++ b/django/contrib/postgres/validators.py
@@ -1,5 +1,9 @@
+import copy
+
+from django.core.exceptions import ValidationError
from django.core.validators import MaxLengthValidator, MinLengthValidator
-from django.utils.translation import ungettext_lazy
+from django.utils.deconstruct import deconstructible
+from django.utils.translation import ungettext_lazy, ugettext_lazy as _
class ArrayMaxLengthValidator(MaxLengthValidator):
@@ -14,3 +18,48 @@ class ArrayMinLengthValidator(MinLengthValidator):
'List contains %(show_value)d item, it should contain no fewer than %(limit_value)d.',
'List contains %(show_value)d items, it should contain no fewer than %(limit_value)d.',
'limit_value')
+
+
+@deconstructible
+class KeysValidator(object):
+ """A validator designed for HStore to require/restrict keys."""
+
+ messages = {
+ 'missing_keys': _('Some keys were missing: %(keys)s'),
+ 'extra_keys': _('Some unknown keys were provided: %(keys)s'),
+ }
+ strict = False
+
+ def __init__(self, keys, strict=False, messages=None):
+ self.keys = set(keys)
+ self.strict = strict
+ if messages is not None:
+ self.messages = copy.copy(self.messages)
+ self.messages.update(messages)
+
+ def __call__(self, value):
+ keys = set(value.keys())
+ missing_keys = self.keys - keys
+ if missing_keys:
+ raise ValidationError(self.messages['missing_keys'],
+ code='missing_keys',
+ params={'keys': ', '.join(missing_keys)},
+ )
+ if self.strict:
+ extra_keys = keys - self.keys
+ if extra_keys:
+ raise ValidationError(self.messages['extra_keys'],
+ code='extra_keys',
+ params={'keys': ', '.join(extra_keys)},
+ )
+
+ def __eq__(self, other):
+ return (
+ isinstance(other, self.__class__)
+ and (self.keys == other.keys)
+ and (self.messages == other.messages)
+ and (self.strict == other.strict)
+ )
+
+ def __ne__(self, other):
+ return not (self == other)