django.core-validators


发表于10个月前(2014-12-18 17:04)   阅读( 6) | 评论( 00人收藏此文章,我要收藏
赞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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值