1 | Index: core/validators.py
|
---|
2 | ===================================================================
|
---|
3 | --- core/validators.py (revision 17904)
|
---|
4 | +++ core/validators.py (working copy)
|
---|
5 | @@ -33,6 +33,36 @@
|
---|
6 | if not self.regex.search(smart_unicode(value)):
|
---|
7 | raise ValidationError(self.message, code=self.code)
|
---|
8 |
|
---|
9 | +class DomainNameValidator(RegexValidator):
|
---|
10 | + # from URLValidator + there can be most 127 labels (at most 255 total chars)
|
---|
11 | + regex = re.compile(
|
---|
12 | + r'^(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.){0,126}(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?))$',
|
---|
13 | + re.IGNORECASE
|
---|
14 | + )
|
---|
15 | + message = 'Enter a valid domain name value'
|
---|
16 | +
|
---|
17 | + def __init__(self, *args, **kwargs):
|
---|
18 | + self.accept_idna = bool(kwargs.pop('accept_idna', True))
|
---|
19 | + super(DomainNameValidator, self).__init__(*args, **kwargs)
|
---|
20 | + if self.accept_idna:
|
---|
21 | + self.message = 'Enter a valid plain or internationalized domain name value'
|
---|
22 | +
|
---|
23 | + def __call__(self, value):
|
---|
24 | + # validate
|
---|
25 | + try:
|
---|
26 | + super(DomainNameValidator, self).__call__(value)
|
---|
27 | + except ValidationError as e:
|
---|
28 | + # maybe this is a unicode-encoded IDNA string?
|
---|
29 | + if not self.accept_idna: raise
|
---|
30 | + if not value: raise
|
---|
31 | + # convert it unicode -> ascii
|
---|
32 | + try:
|
---|
33 | + asciival = smart_unicode(value).encode('idna')
|
---|
34 | + except UnicodeError:
|
---|
35 | + raise e # raise the original ASCII error
|
---|
36 | + # validate the ascii encoding of it
|
---|
37 | + super(DomainNameValidator, self).__call__(asciival)
|
---|
38 | +
|
---|
39 | class URLValidator(RegexValidator):
|
---|
40 | regex = re.compile(
|
---|
41 | r'^(?:http|ftp)s?://' # http:// or https://
|
---|