-
Notifications
You must be signed in to change notification settings - Fork 0
/
field.py
92 lines (71 loc) · 2.82 KB
/
field.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
import re
from sqlalchemy import Unicode, String
from sqlalchemy_dict import Field as SADictField
from nanohttp import HTTPBadRequest
# noinspection PyAbstractClass
class Field(SADictField):
def __init__(self,
*args,
max_length=None,
min_length=None,
pattern=None,
watermark=None,
nullable=False,
label=None,
icon=None,
example=None,
message=None,
collation=None,
info=None,
**kwargs):
info = info or dict()
if watermark is not None:
info['watermark'] = watermark
if max_length is not None:
info['max_length'] = max_length
elif args and isinstance(args[0], (Unicode, String)):
info['max_length'] = args[0].length
if min_length is not None:
info['min_length'] = min_length
if pattern is not None:
info['pattern'] = pattern
if label is not None:
info['label'] = label
if icon is not None:
info['icon'] = icon
if example is not None:
info['example'] = example
if message is not None:
info['message'] = message
if collation is not None:
info['collation'] = collation
super(Field, self).__init__(*args, info=info, nullable=nullable, **kwargs)
@property
def can_validate(self):
return 'pattern' in self.info or \
'min_length' in self.info or \
'max_length' in self.info
def _validate_pattern(self, value):
if value is None:
return
if not re.match(self.info['pattern'], value):
raise HTTPBadRequest('Cannot match field: %s with value "%s" by acceptable pattern' % (self.name, value))
return value
def _validate_length(self, value, min_length, max_length):
if value is None:
return
if not isinstance(value, str):
raise HTTPBadRequest('Invalid type: %s for field: %s' % (type(value), self.name))
value_length = len(value)
if min_length is not None:
if value_length < min_length:
raise HTTPBadRequest('Please enter at least %d characters for field: %s.' % (min_length, self.name))
if max_length is not None:
if value_length > max_length:
raise HTTPBadRequest('Cannot enter more than: %d in field: %s.' % (max_length, self.name))
def validate(self, value):
if 'pattern' in self.info:
self._validate_pattern(value)
if 'min_length' in self.info or 'max_length' in self.info:
self._validate_length(value, self.info.get('min_length'), self.info.get('max_length'))
return value