import copy, re
from django.core import validators
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.utils.deconstruct import deconstructible
from django.utils.translation import gettext_lazy as _
__all__ = ['EmptyValidator', 'KeysValidator', 'MD5ChecksumValidator']
[docs]class EmptyValidator(validators.RegexValidator):
regex = r'\S+'
message = _('This field cannot be blank.')
code = 'blank'
[docs]@deconstructible
class KeysValidator(object):
"""
A validator designed for HStore to require, even restrict keys.
Code mostly borrowed from:
https://github.com/django/django/blob/master/django/contrib/postgres/validators.py
"""
messages = {
'missing_keys': _('Some keys were missing: %(keys)s'),
'extra_keys': _('Some unknown keys were provided: %(keys)s'),
}
strict = False
[docs] def __init__(self, required_keys=None, optional_keys=None, strict=False, messages=None):
self.required_keys = set(required_keys or [])
self.optional_keys = set(optional_keys or [])
if not self.required_keys and not self.optional_keys:
raise ImproperlyConfigured('You must set at least `required_keys` or `optional_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())
if self.required_keys:
missing_keys = self.required_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.required_keys - self.optional_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.required_keys == other.required_keys
and self.optional_keys == other.optional_keys
and self.messages == other.messages
and self.strict == other.strict
)
def __ne__(self, other):
return not self == other
[docs]class MD5ChecksumValidator(validators.RegexValidator):
regex = re.compile(r'[0-9a-f]{32}')