from __future__ import unicode_literals import re from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _, ungettext_lazy from django.utils.encoding import force_text from django.utils.ipv6 import is_valid_ipv6_address from django.utils import six from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit # These values, if given to validate(), will trigger the self.required check. EMPTY_VALUES = (None, '', [], (), {}) class RegexValidator(object): regex = '' message = _('Enter a valid value.') code = 'invalid' def __init__(self, regex=None, message=None, code=None): if regex is not None: self.regex = regex if message is not None: self.message = message if code is not None: self.code = code # Compile the regex if it was not passed pre-compiled. if isinstance(self.regex, six.string_types): self.regex = re.compile(self.regex) def __call__(self, value): """ Validates that the input matches the regular expression. """ if not self.regex.search(force_text(value)): raise ValidationError(self.message, code=self.code) class URLValidator(RegexValidator): regex = re.compile( r'^(?:http|ftp)s?://' # http:// or https:// r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}(? ACE except UnicodeError: # invalid domain part raise e url = urlunsplit((scheme, netloc, path, query, fragment)) super(URLValidator, self).__call__(url) else: raise else: url = value def validate_integer(value): try: int(value) except (ValueError, TypeError): raise ValidationError(_('Enter a valid integer.'), code='invalid') class EmailValidator(object): message = _('Enter a valid email address.') code = 'invalid' user_regex = re.compile( r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$" # dot-atom r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"$)', # quoted-string re.IGNORECASE) domain_regex = re.compile( r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,}(? b message = _('Ensure this value is less than or equal to %(limit_value)s.') code = 'max_value' class MinValueValidator(BaseValidator): compare = lambda self, a, b: a < b message = _('Ensure this value is greater than or equal to %(limit_value)s.') code = 'min_value' class MinLengthValidator(BaseValidator): compare = lambda self, a, b: a < b clean = lambda self, x: len(x) message = ungettext_lazy( 'Ensure this value has at least %(limit_value)d character (it has %(show_value)d).', 'Ensure this value has at least %(limit_value)d characters (it has %(show_value)d).', 'limit_value') code = 'min_length' class MaxLengthValidator(BaseValidator): compare = lambda self, a, b: a > b clean = lambda self, x: len(x) message = ungettext_lazy( 'Ensure this value has at most %(limit_value)d character (it has %(show_value)d).', 'Ensure this value has at most %(limit_value)d characters (it has %(show_value)d).', 'limit_value') code = 'max_length'