上一篇简单的叙述了CSRF这个中间件的作用,他在执行视图函数之前可以对csrftoken进行验证,如果通过才执行否则直接报错。
那么什么是中间件呢?这个要回到Django的生命周期里面。一个基本的生命周期是用户输入一个URL,通过urls.py找到对应的视图函数,然后进行数据处理,返回渲染后的结果。在url和视图函数的匹配过程中,还有一个重要的过程,就是依次执行所有的中间件的类里面的函数。
还是以csrf中间件为例,看看他的源码截图如下,他继承了一个MiddlewareMixin 类,里面还定义了一些特殊的固定名字的函数,例如 process_view, process_response等等,如果需要自定义一个中间件,我们也需要这些东西。
下面看看实例来解释他们的用途。
定义一个m1.py文件,里面是我们自定义的中间件,这里创建了3个类,每个类就是一个中间件
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
|
rom django.utils.deprecation
import
MiddlewareMixin
class
Row1(MiddlewareMixin):
def
process_request(
self
,request):
print
(
'R11'
)
def
process_view(
self
, request, view_func, view_func_args, view_func_kwargs):
print
(
'R12'
)
def
process_response(
self
, request, response):
print
(
'R13'
)
return
response
from
django.shortcuts
import
HttpResponse
class
Row2(MiddlewareMixin):
def
process_request(
self
,request):
print
(
'R21'
)
# return HttpResponse('走')
def
process_view(
self
, request, view_func, view_func_args, view_func_kwargs):
print
(
'R22'
)
def
process_response(
self
, request, response):
print
(
'R23'
)
return
response
class
Row3(MiddlewareMixin):
def
process_request(
self
,request):
print
(
'R31'
)
def
process_view(
self
, request, view_func, view_func_args, view_func_kwargs):
print
(
'R32'
)
def
process_response(
self
, request, response):
print
(
'R33'
)
return
response
def
process_exception(
self
, request, exception):
if
isinstance
(exception,ValueError):
return
HttpResponse(
'出现异常》。。'
)
def
process_template_response(
self
,request,response):
# 如果Views中的函数返回的对象中,具有render方法
print
(
'-----------------------'
)
return
response
|
下面是系统默认的中间件配置,他的执行顺序是从上往下执行的。如果需要添加自定义的中间件,可以直接添加在下面
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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'
,
'Middle.m1.Row1'
,
'Middle.m1.Row2'
,
'Middle.m1.Row3'
,
]
|
最后是我的视图函数
1
2
3
|
def
test(request):
print
(
'执行View函数'
)
return
HttpResponse(
'ok'
)
|
整个流程的执行顺序是发送Url请求,然后中间件按从上到下顺序执行自己的 process_request函数,然后掉过头来再从上到下执行process_view函数,然后到达视图函数,如果有错误,按照从下往上的顺序来执行 process_exception函数,如果无误,执行每个中间件的process_response函数
下图转自网络
因此如果输入http://127.0.0.1:8000/test ,控制台输出结果是
1
2
3
4
5
6
7
8
9
10
|
R11
R21
R31
R12
R22
R32
执行View函数
R33
R23
R13
|
如果在process_view里面执行了HttpResponse的返回操作,那么他会直接跳过process_view和视图函数,而直接跳到当前中间件的process_response,然后一路返回
例如:修改Row2
1
2
3
4
5
|
from
django.shortcuts
import
HttpResponse
class
Row2(MiddlewareMixin):
def
process_request(
self
,request):
print
(
'R21'
)
return
HttpResponse(
'走'
)
|
那么结果直接显示
1
2
3
4
|
R11
R21
R23
R13
|
如果我故意执行一个报错的代码,比如
1
2
3
4
|
def
test(request):
print
(
'执行View函数'
)
int
(
'sdsfsdfs'
)
return
HttpResponse(
'ok'
)
|