-
Notifications
You must be signed in to change notification settings - Fork 31
/
url.py
136 lines (101 loc) · 4.81 KB
/
url.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""
url form/model field
~~~~~~~~~~~~~~~~~~~~
flexible URL form and model field used own URLValidator2.
:copyleft: 2011-2016 by the django-tools team, see AUTHORS for more details.
:license: GNU GPL v3 or above, see LICENSE for more details.
"""
from django.db.models.fields import CharField as OriginModelCharField
from django.forms.fields import CharField as OriginFormsCharField
from django.utils.translation import gettext_lazy as _
from django_tools.validators import URLValidator2
class URLFormField2(OriginFormsCharField):
"""
A flexible version of the original django form URLField ;)
Please read the django_tools.validators.URLValidator2 DocString, too!
To allow only local domains, disallow scheme and netloc:
>>> URLFormField2(allow_schemes=None, allow_netloc=False).clean("/path/?query#fragment")
'/path/?query#fragment'
>>> try:
... URLFormField2(allow_schemes=None, allow_netloc=False).clean("http://domain.tld/path/?query#fragment")
... except Exception as err:
... print(err.__class__.__name__, err)
ValidationError ['Please enter a local URL (without protocol/domain).']
**Note:** this is also a valid "local" path (more info in URLValidator2 DocString):
>>> URLFormField2(allow_schemes=None, allow_netloc=False).clean("domain.tld/path/?query#fragment")
'domain.tld/path/?query#fragment'
>>> URLFormField2(allow_schemes=("svn",)).clean("svn://domain.tld")
'svn://domain.tld'
>>> try:
... URLFormField2(allow_schemes=("http","ftp")).clean("svn://domain.tld")
... except Exception as err:
... print(err.__class__.__name__, err)
ValidationError ["The URL doesn't start with a allowed scheme."]
"""
default_error_messages = {
'invalid': _('Enter a valid URL.'),
'invalid_link': _('This URL appears to be a broken link.'),
}
def __init__(self, max_length=None, min_length=None, verify_exists=False,
allow_schemes=("http", "https"), allow_all_schemes=False, allow_netloc=True,
allow_query=True, allow_fragment=True, **kwargs):
super().__init__(max_length=max_length, min_length=min_length, **kwargs)
self.validators.append(
URLValidator2(
allow_schemes=allow_schemes, allow_all_schemes=allow_all_schemes, allow_netloc=allow_netloc,
allow_query=allow_query, allow_fragment=allow_fragment
)
)
class URLModelField2(OriginModelCharField):
"""
A flexible version of the original django model URLField ;)
Please read the django_tools.validators.URLValidator2 DocString, too!
>>> f = URLModelField2(verify_exists=False).formfield()
>>> isinstance(f, URLFormField2)
True
>>> f.clean("http://www.domain.tld/path?query#fragment")
'http://www.domain.tld/path?query#fragment'
>>> f = URLModelField2().formfield()
>>> try:
... f.clean("svn://domain.tld")
... except Exception as err:
... print(err.__class__.__name__, err)
ValidationError ["The URL doesn't start with a allowed scheme."]
>>> f = URLModelField2(allow_query=False).formfield()
>>> f.clean("http://www.domain.tld/without/query/")
'http://www.domain.tld/without/query/'
>>> try:
... f.clean("http://www.domain.tld/with/?query")
... except Exception as err:
... print(err.__class__.__name__, err)
ValidationError ['Enter a valid URL without a query.']
"""
description = _("URL")
def __init__(self, verbose_name=None, name=None, verify_exists=True,
allow_schemes=("http", "https"), allow_all_schemes=False, allow_netloc=True,
allow_query=True, allow_fragment=True, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 200)
OriginModelCharField.__init__(self, verbose_name, name, **kwargs)
self.allow_schemes = allow_schemes or ()
self.allow_all_schemes = allow_all_schemes
self.allow_netloc = allow_netloc
self.allow_query = allow_query
self.allow_fragment = allow_fragment
self.validators.append(
URLValidator2(
allow_schemes=allow_schemes, allow_all_schemes=allow_all_schemes, allow_netloc=allow_netloc,
allow_query=allow_query, allow_fragment=allow_fragment
)
)
def formfield(self, **kwargs):
# As with CharField, this will cause URL validation to be performed twice
defaults = {
'form_class': URLFormField2,
"allow_schemes": self.allow_schemes,
"allow_all_schemes": self.allow_all_schemes,
"allow_netloc": self.allow_netloc,
"allow_query": self.allow_query,
"allow_fragment": self.allow_fragment,
}
defaults.update(kwargs)
return super().formfield(**defaults)