django form表单插件,中间件,缓存,信号

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介:
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
一、form插件
django form表单类的字段和插件,字段用于表单验证获取数据,插件用来生成html代码
Field
     required = True ,               是否允许为空
     widget = None ,                 HTML插件
     label = None ,                  用于生成Label标签或显示内容
     initial = None ,                初始值
     help_text = '',                帮助信息(在标签旁边显示)
     error_messages = None ,         错误信息 { 'required' '不能为空' 'invalid' '格式错误' }
     show_hidden_initial = False ,   是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
     validators = [],               自定义验证规则
     localize = False ,              是否支持本地化
     disabled = False ,              是否可以编辑
     label_suffix = None             Label内容后缀
     
 
CharField(Field)
     max_length = None ,             最大长度
     min_length = None ,             最小长度
     strip = True                    是否移除用户输入空白
 
IntegerField(Field)
     max_value = None ,              最大值
     min_value = None ,              最小值
     
DecimalField(IntegerField)
     max_value = None ,              最大值
     min_value = None ,              最小值
     max_digits = None ,             总长度
     decimal_places = None ,         小数位长度
     
RegexField(CharField)
     regex,                      自定制正则表达式
     max_length = None ,            最大长度
     min_length = None ,            最小长度
     error_message = None ,         忽略,错误信息使用 error_messages = { 'invalid' '...' }
 
EmailField(CharField)
FileField(Field)
     allow_empty_file = False      是否允许空文件
 
ChoiceField(Field)
     ...
     choices = [],                选项,如:choices  =  [( 0 , '上海' ),( 1 , '北京' ),]
     required = True ,             是否必填
     widget = None ,               插件,默认select插件
     label = None ,                Label内容
     initial = None ,              初始值
     help_text = '',              帮助提示
     
FilePathField(ChoiceField)     文件选项,目录下文件显示在页面中
     path,                      文件夹路径
     match = None ,                正则匹配
     recursive = False ,           递归下面的文件夹
     allow_files = True ,          允许文件
     allow_folders = False ,       允许文件夹
     required = True ,
     widget = None ,
     label = None ,
     initial = None ,
     help_text = ''
 
GenericIPAddressField
     protocol = 'both' ,           both,ipv4,ipv6支持的IP格式
     unpack_ipv4 = False           解析ipv4地址,如果是::ffff: 192.0 . 2.1 时候,可解析为 192.0 . 2.1 , PS:protocol必须为both才能启用
1
二、form验证规则
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
新建模块forms.py
from  django.forms  import  Form
from  django.forms  import  fields
from  django.forms  import  widgets
from  app01  import  models
import  re
from  django.core.exceptions  import  ValidationError
from  django.core.validators  import  RegexValidator
 
class  UserInfoForm(Form):
     name  =  fields.CharField(
         required = True ,
         min_length = 6 ,
         max_length = 12
     )
     email  =  fields.EmailField(
         required = True ,
     )
     方法一: RegexValidator对象
     phone  =  fields.CharField(
         validators = [RegexValidator(r '^[0-9]+$' '请输入数字' ), RegexValidator(r '^159[0-9]+$' '数字必须以159开头' )]
      )
      
     方式二:函数
     def  mobile_validate(value):
     mobile_re  =  re. compile (r '^(13[0-9]|15[0123456789]|17[678]|18[0-9]|14[57])[0-9]{8}$' )
     if  not  mobile_re.match(value):
         raise  ValidationError( '手机号码格式错误' )
         
     phone  =  fields.CharField(
          validators =  [mobile_validate,]
      )
      
     方法三:当前类的方法中,方法名称要求: clean_phone方法
     phone  =  fields.CharField()
     
     def  clean_phone( self ):
         # 去取用户提交的值:可能是错误的,可能是正确
         value  =  self .cleaned_data[ 'phone' ]
         mobile_re  =  re. compile (r '^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$' )
         if  not  mobile_re.match(value):
             raise  ValidationError( '手机号码格式错误' )
 
         if  models.UserInfo.objects. filter (phone = value).count():
             raise  ValidationError( '手机号码已经存在' )
 
         return  value
         
  注册确认密码认证clean函数
  class  RegisterForm(Form):
     name  =  fields.CharField(
         widget = widgets.TextInput(attrs = { 'class' 'c1' })
     )
 
     email  =  fields.EmailField(
         widget = widgets.EmailInput(attrs = { 'class' 'c1' })
     )
 
     phone  =  fields.CharField(
         widget = widgets.Textarea(attrs = { 'class' 'c1' })
     )
 
     pwd  =  fields.CharField(
         widget = widgets.PasswordInput(attrs = { 'class' 'c1' })
     )
 
     pwd_confirm  =  fields.CharField(
         widget = widgets.PasswordInput(attrs = { 'class' 'c1' })
     )
 
     dp_id  =  fields.ChoiceField(
         choices = []
     )
 
     roles_id  =  fields.ChoiceField(
         choices = []
     )
 
     def  __init__( self * args,  * * kwargs):
         super (RegisterForm,  self ).__init__( * args,  * * kwargs)
         self .fields[ 'dp_id' ].choices  =  models.Depart.objects.values_list( 'id' 'title' )
         self .fields[ 'roles_id' ].choices  =  models.Role.objects.values_list( 'id' 'name' )
 
     def  clean( self ):
         pwd  =  self .cleaned_data[ 'pwd' ]
         pwd_confirm  =  self .cleaned_data[ 'pwd_confirm' ]
         if  pwd  = =  pwd_confirm:
             return  self .cleaned_data
         else :
             from  django.core.exceptions  import  ValidationError
             self .add_error( 'pwd_confirm' , ValidationError( '密码输入不一致' ))
             return  self .cleaned_data
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
三、中间件
项目目录下新建目录md
md目录新建middleware.py文件
from  django.shortcuts  import  HttpResponse,redirect
 
class  MiddlewareMixin:
     def  __init__( self , get_response = None ):
         self .get_response  =  get_response
         super (MiddlewareMixin, self ).__init__()
 
     def  __call__( self , request):
         response  =  None
         if  hasattr ( self 'process_request' ):
             response  =  self .process_request(request)
         if  not  response:
             response  =  self .get_response(request)
         if  hasattr ( self 'process_response' ):
             response  =  self .process_response(request, response)
         return  response
 
class  M1(MiddlewareMixin):
     def  process_request( self , request):
         print ( 'm1.process_request' )
 
     def  process_view( self , request, callback, callback_args, callback_kwargs):
         print ( 'm1.process_view' , callback)
 
     def  process_exception( self ,request,exception):
         print ( 'm1.process_exception' )
 
     def  process_response( self ,request,response):
         print ( 'm1.process_response' )
         return  response
 
class  M2(MiddlewareMixin):
     def  process_request( self , request):
         print ( 'm2.process_request' )
 
     def  process_view( self ,request,callback, callback_args, callback_kwargs):
         print ( 'm2.process_view' , callback)
 
     def   process_response( self ,request, response):
         print ( 'm2.process_response' )
         return  response
 
     def  process_exception( self ,request,exception):
         print ( 'm2.process_exception' )
         
         
  settings.py文件中间件添加
MIDDLEWARE  =  [
     'django.middleware.security.SecurityMiddleware' ,
     'django.contrib.sessions.middleware.SessionMiddleware' ,
     'django.middleware.common.CommonMiddleware' ,
     'django.middleware.csrf.CsrfViewMiddleware' ,
     'django.contrib.auth.middleware.AuthenticationMiddleware' ,
     'django.contrib.messages.middleware.MessageMiddleware' ,
     'django.middleware.clickjacking.XFrameOptionsMiddleware' ,
     'md.middleware.M1' ,     #添加项
     'md.middleware.M2' ,     #添加项
]
 
 
中间件是一个类
中间件中一共有四个方法:
process_request
process_view
process_exception
process_response
 
 
已经添加中间件M1和M2
中间件执行时机: 请求到来,请求返回时
-  应用:
     -  请求日志
     -  用户登录认证

wKioL1m_hbXh99ymAABUHI-DJ4M285.jpg-wh_50

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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
四、缓存
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会
更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,
5 分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿
到,并返回
 
Django中提供了 6 种缓存方式:
1.  开发调试
2.  内存
3.  文件
4.  数据库
5.  Memcache缓存(python - memcached模块)
6.  Memcache缓存(pylibmc模块)
 
a.开发调试
# 此为开始调试用,实际内部不做任何操作
# 配置:
CACHES  =  {            
     'default' : {               
          'BACKEND' 'django.core.cache.backends.dummy.DummyCache' ,      # 引擎
          'TIMEOUT' 300 # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
          'OPTIONS' :{
              'MAX_ENTRIES' 300 # 最大缓存个数(默认300)
              'CULL_FREQUENCY' 3 ,     # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
              },
          'KEY_PREFIX' : '',  # 缓存key的前缀(默认空)  
          'VERSION' 1 ,      # 缓存key的版本(默认1)
          'KEY_FUNCTION'  函数名     # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
        }
      }
      
      
  def  default_key_func(key, key_prefix, version):
      return  '%s:%s:%s'  %  (key_prefix, version, key)
      
  def  get_key_func(key_func):
      if  key_func  is  not  None :            
          if  callable (key_func):                
              return  key_func            
          else :                
              return  import_string(key_func)        
      return  default_key_func
      
      
  b. 内存缓存
   此缓存将内容保存至内存的变量中
   # 配置:
   CACHES  =  {           
        'default' : {                
            'BACKEND' 'django.core.cache.backends.locmem.LocMemCache' ,                
            'LOCATION' 'unique-snowflake' ,
             }
         }
    
c. 文件缓存
# 此缓存将内容保存至文件
     # 配置:
         CACHES  =  {            
             'default' : {                
                 'BACKEND' 'django.core.cache.backends.filebased.FileBasedCache' ,  
                 'LOCATION' '/var/tmp/django_cache' ,
             }
         }
         
d. 数据库缓存
# 此缓存将内容保存至数据库
 
     # 配置:
         CACHES  =  {            
             'default' : {               
                  'BACKEND' 'django.core.cache.backends.db.DatabaseCache' ,                
                  'LOCATION' 'my_cache_table' # 数据库表                           
              }
         }
         
e. Memcache缓存(python - memcached模块)
# 此缓存使用python-memcached模块连接memcache
     CACHES  =  {        
         'default' : {            
             'BACKEND' 'django.core.cache.backends.memcached.MemcachedCache' ,           
              'LOCATION' '127.0.0.1:11211' ,
         }
     }
 
     CACHES  =  {       
          'default' : {            
              'BACKEND' 'django.core.cache.backends.memcached.MemcachedCache' ,           
               'LOCATION' 'unix:/tmp/memcached.sock' ,
         }
     }   
 
     CACHES  =  {       
          'default' : {            
              'BACKEND' 'django.core.cache.backends.memcached.MemcachedCache' ,           
               'LOCATION' : [ 
               '172.19.26.240:11211' ,                
               '172.19.26.242:11211' ,
             ]
         }
     }
 
     
  f. Memcache缓存(pylibmc模块)
  # 此缓存使用pylibmc模块连接memcache    
     CACHES  =  {        
         'default' : {            
             'BACKEND' 'django.core.cache.backends.memcached.PyLibMCCache' ,            
             'LOCATION' '127.0.0.1:11211' ,
         }
     }
 
     CACHES  =  {        
         'default' : {            
             'BACKEND' 'django.core.cache.backends.memcached.PyLibMCCache' ,            
             'LOCATION' '/tmp/memcached.sock' ,
         }
     }   
 
     CACHES  =  {        
         'default' : {            
             'BACKEND' 'django.core.cache.backends.memcached.PyLibMCCache' ,           
              'LOCATION' : [                
                  '172.19.26.240:11211' ,                
                  '172.19.26.242:11211' ,
             ]
         }
     }
     
     
缓存使用方法
1.  全站应用配置
使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获
取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则
UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存
 
MIDDLEWARE  =  [       
          'django.middleware.cache.UpdateCacheMiddleware' ,         # 其他中间件...
          'django.middleware.cache.FetchFromCacheMiddleware' ,
     ]
 
     #CACHE_MIDDLEWARE_ALIAS = ""
    # CACHE_MIDDLEWARE_SECONDS = ""
    # CACHE_MIDDLEWARE_KEY_PREFIX = ""
     
2. 单独视图函数
方式一:        
from  django.views.decorators.cache  import  cache_page
 
@cache_page ( 60  *  15 )        
def  my_view(request):
             ...
 
方式二:        
from  django.views.decorators.cache  import  cache_page
 
urlpatterns  =  [
     url(r '^foo/([0-9]{1,2})/$' , cache_page( 60  *  15 )(my_view)),
     ]
     
     
3. 局部视图使用
a. 引入TemplateTag
 
         { %  load cache  % }
 
b. 使用缓存
 
         { %  cache  5000  缓存key  % }
             缓存内容
         { %  endcache  % }
         
五、信号
1. 内置信号
Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,
信号允许特定的发送者去提醒一些接受者
 
Model signals
     pre_init                     # django的modal执行其构造方法前,自动触发
     post_init                    # django的modal执行其构造方法后,自动触发
     pre_save                     # django的modal对象保存前,自动触发
     post_save                    # django的modal对象保存后,自动触发
     pre_delete                   # django的modal对象删除前,自动触发
     post_delete                  # django的modal对象删除后,自动触发
     m2m_changed                  # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
     class_prepared               # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals
     pre_migrate                  # 执行migrate命令前,自动触发
     post_migrate                 # 执行migrate命令后,自动触发
Request / response signals
     request_started              # 请求到来前,自动触发
     request_finished             # 请求结束后,自动触发
     got_request_exception        # 请求异常后,自动触发
Test signals
     setting_changed              # 使用test测试修改配置文件时,自动触发
     template_rendered            # 使用test测试渲染模板时,自动触发
Database Wrappers
     connection_created           # 创建数据库连接时,自动触发
     
对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:
 
from  django.core.signals  import  request_finished    
from  django.core.signals  import  request_started    
from  django.core.signals  import  got_request_exception    
from  django.db.models.signals  import  class_prepared    
from  django.db.models.signals  import  pre_init, post_init    
from  django.db.models.signals  import  pre_save, post_save    
from  django.db.models.signals  import  pre_delete, post_delete    
from  django.db.models.signals  import  m2m_changed    
from  django.db.models.signals  import  pre_migrate, post_migrate    
from  django.test.signals  import  setting_changed    
from  django.test.signals  import  template_rendered    
from  django.db.backends.signals  import  connection_created    
 
def  callback(sender,  * * kwargs):        
     print ( "xxoo_callback" )        
     print (sender,kwargs)
 
xxoo.connect(callback)     # xxoo指上述导入的内容
 
 
例子:
from  django.core.signals  import  request_finished
from  django.dispatch  import  receiver
 
@receiver (request_finished)
def  my_callback(sender,  * * kwargs):    
     print ( "Request finished!" )
     
2. 自定义信号
a. 定义信号
import  django.dispatch
pizza_done  =  django.dispatch.Signal(providing_args = [ "toppings" "size" ])
 
b. 注册信号
def  callback(sender,  * * kwargs):
     print ( "callback" )
     print (sender,kwargs)
  
pizza_done.connect(callback)
 
c. 触发信号
from  路径  import  pizza_done
  
pizza_done.send(sender = 'seven' ,toppings = 123 , size = 456 )
 
 
例子请求后打印一行数据: 配置在urls.py一层目录下面的__init__.py文件中
from  django.core.signals  import  request_finished
from  django.core.signals  import  request_started
from  django.core.signals  import  got_request_exception
 
from  django.db.models.signals  import  class_prepared
from  django.db.models.signals  import  pre_init, post_init
from  django.db.models.signals  import  pre_save, post_save
from  django.db.models.signals  import  pre_delete, post_delete
from  django.db.models.signals  import  m2m_changed
from  django.db.models.signals  import  pre_migrate, post_migrate
 
from  django.test.signals  import  setting_changed
from  django.test.signals  import  template_rendered
 
from  django.db.backends.signals  import  connection_created
 
 
def  test(sender,  * * kwargs):
     print ( "request_finished.222" )
     print (sender, kwargs)
 
request_started.connect(test)     #请求开始时打印
request_finished.connect(test)     #请求结束后打印





     本文转自小白的希望 51CTO博客,原文链接:http://blog.51cto.com/haoyonghui/1966329 ,如需转载请自行联系原作者






相关文章
|
4月前
|
中间件 程序员 开发工具
Django实践-08中间件的应用
Django实践-08中间件的应用
Django实践-08中间件的应用
|
1月前
|
数据库 开发者 UED
如何使用Django的Form组件
如何使用Django的Form组件
24 0
|
6月前
|
存储 缓存 API
Django缓存的使用方法
Django缓存的使用方法
|
8月前
|
调度 数据库 开发者
django -- 信号
django -- 信号
|
8月前
|
缓存 中间件 数据库
django -- 缓存
django -- 缓存
|
8月前
|
数据库 数据安全/隐私保护 Python
|
8月前
|
前端开发 中间件 数据安全/隐私保护
【Django】创建用户,中间件,表单组件
【Django】创建用户,中间件,表单组件
47 0
|
8月前
|
XML 中间件 数据格式
Django 高级指南:深入理解和使用类视图和中间件
Django 是一款强大的 Python Web 框架,它提供了一套完整的解决方案,让我们能够用 Python 语言快速开发和部署复杂的 Web 应用。在本文中,我们将会深入研究 Django 中的两个高级特性:类视图(Class-Based Views)和中间件(Middleware)。
|
4月前
|
缓存 中间件 Python
Python Web 开发: 解释 Django 中的中间件是什么,以及如何使用?
Python Web 开发: 解释 Django 中的中间件是什么,以及如何使用?
|
5月前
|
缓存 监控 NoSQL
一个.Net Core开源缓存中间件,让你更加简单、方便使用缓存
一个.Net Core开源缓存中间件,让你更加简单、方便使用缓存
137 0