-
Notifications
You must be signed in to change notification settings - Fork 73
/
decorators.py
74 lines (62 loc) · 2.3 KB
/
decorators.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
import re
from django import forms
FIELD_TYPES = [
(forms.URLField, "url"),
(forms.EmailField, "email"),
(forms.IntegerField, "digits"),
(forms.DecimalField, "number"),
(forms.FloatField, "number"),
]
FIELD_ATTRS = [
("min_length", "minlength"),
("max_length", "maxlength"),
("min_value", "min"),
("max_value", "max"),
]
def update_widget_attrs(field):
attrs = field.widget.attrs
if field.required:
attrs["data-required"] = "true"
if isinstance(field, forms.RegexField):
attrs.update({"data-regexp": field.regex.pattern})
if field.regex.flags & re.IGNORECASE:
attrs.update({"data-regexp-flag": "i"})
if isinstance(field, forms.MultiValueField):
for subfield in field.fields:
update_widget_attrs(subfield)
# Set data-* attributes for parsley based on Django field attributes
for attr, data_attr, in FIELD_ATTRS:
if getattr(field, attr, None):
attrs["data-{0}".format(data_attr)] = getattr(field, attr)
# Set data-type attribute based on Django field instance type
for klass, field_type in FIELD_TYPES:
if isinstance(field, klass):
attrs["data-type"] = field_type
def parsleyfy(klass):
"A decorator to add data-* attributes to your form.fields"
old_init = klass.__init__
def new_init(self, *args, **kwargs):
old_init(self, *args, **kwargs)
for _, field in self.fields.items():
update_widget_attrs(field)
extras = getattr(getattr(self, 'Meta', None), 'parsley_extras', {})
for field_name, data in extras.items():
for key, value in data.items():
if field_name not in self.fields:
continue
attrs = self.fields[field_name].widget.attrs
if key == 'equalto':
# Use HTML id for data-equalto
attrs['data-equalto'] = '#' + self[value].id_for_label
else:
attrs['data-%s' % key] = value
klass.__init__ = new_init
try:
klass.Media.js += ("parsley/js/parsley-standalone.min.js",)
except AttributeError:
class Media:
js = (
"parsley/js/parsley-standalone.min.js",
)
klass.Media = Media
return klass