赞0
摘要
validators模块,主要是根据一定的规则检验数据的。如果不符合,就抛出ValidationError异常。
这里validators模块主要的特点是, 用类继承来模仿函数的调用。具体实现:定义class的__call__方法。
并且往往子类通过重新定义父类的属性,来达到继承的效果。
|
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
|
@deconstructible
class
BaseValidator(
object
):
compare
=
lambda
self
, a, b: a
is
not
b
clean
=
lambda
self
, x: x
message
=
_(
'Ensure this value is %(limit_value)s (it is %(show_value)s).'
)
code
=
'limit_value'
def
__init__(
self
, limit_value, message
=
None
):
self
.limit_value
=
limit_value
if
message:
self
.message
=
message
def
__call__(
self
, value):
cleaned
=
self
.clean(value)
params
=
{
'limit_value'
:
self
.limit_value,
'show_value'
: cleaned,
'value'
: value}
if
self
.compare(cleaned,
self
.limit_value):
raise
ValidationError(
self
.message, code
=
self
.code, params
=
params)
def
__eq__(
self
, other):
return
(
isinstance
(other,
self
.__class__)
and
(
self
.limit_value
=
=
other.limit_value)
and
(
self
.message
=
=
other.message)
and
(
self
.code
=
=
other.code)
)
|
BaseValidator是一个基类,MaxValueValidator,MinValueValidator, MinLengthValidator, MaxLengthValidator都是它的子类。其中clean属性负责生成比较值, compare属性负责比较规则。limit_value是有__init__方法初始化的,用于compare的参数。
|
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
|
@deconstructible
class
MaxValueValidator(BaseValidator):
compare
=
lambda
self
, a, b: a > b
message
=
_(
'Ensure this value is less than or equal to %(limit_value)s.'
)
code
=
'max_value'
@deconstructible
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'
@deconstructible
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'
@deconstructible
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'
|
deconstructible是一个类装饰器,主要功能是增加了deconstruct方法和_constructor_args属性。deconstruct方法主要返回模块名和类名,_constructor_args参数。
|
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
|
def
deconstructible(
*
args,
*
*
kwargs):
"""
Class decorator that allow the decorated class to be serialized
by the migrations subsystem.
Accepts an optional kwarg `path` to specify the import path.
"""
path
=
kwargs.pop(
'path'
,
None
)
def
decorator(klass):
def
__new__(
cls
,
*
args,
*
*
kwargs):
# We capture the arguments to make returning them trivial
obj
=
super
(klass,
cls
).__new__(
cls
)
obj._constructor_args
=
(args, kwargs)
return
obj
def
deconstruct(obj):
"""
Returns a 3-tuple of class import path, positional arguments,
and keyword arguments.
"""
# Python 2/fallback version
if
path:
module_name, _, name
=
path.rpartition(
'.'
)
else
:
module_name
=
obj.__module__
name
=
obj.__class__.__name__
# Make sure it's actually there and not an inner class
module
=
import_module(module_name)
if
not
hasattr
(module, name):
raise
ValueError(
"Could not find object %s in %s.\n"
"Please note that you cannot serialize things like inner "
"classes. Please move the object into the main module "
"body to use migrations.\n"
"For more information, see "
"https://docs.djangoproject.com/en/dev/topics/migrations/#serializing-values"
%
(name, module_name))
return
(
path
or
'%s.%s'
%
(obj.__class__.__module__, name),
obj._constructor_args[
0
],
obj._constructor_args[
1
],
)
klass.__new__
=
staticmethod
(__new__)
klass.deconstruct
=
deconstruct
return
klass
if
not
args:
return
decorator
return
decorator(
*
args,
*
*
kwargs)
|

1万+

被折叠的 条评论
为什么被折叠?



