博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django之中间件
阅读量:5814 次
发布时间:2019-06-18

本文共 4639 字,大约阅读时间需要 15 分钟。

一、什么是Django中间件

    中间件是一个钩子框架,它们可以介入Django 的请求和响应处理过程。它是一个轻量级、底层的“插件”系统,用于在全局修改Django 的输入或输出。每个中间件组件负责完成某个特定的功能。例如:“django.middleware.csrf.CsrfViewMiddleware”中间件的功能是防止POST跨域请求,除非在请求中带了csrf_token才会通过。

二、怎样激活中间件

    我们在setting.py文件中配置中间件,在Django1.10之前叫“MIDDLEWARE_CLASSES”,从Django1.10开始就叫“MIDDLEWARE”。

1
2
3
4
5
6
7
8
9
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'
,
]

三、中间件执行流程

从用户request到response返回,每一个中间件中可以定义五种处理函数:

1
2
3
4
5
process_request(
self
,request)
process_view(
self
, request, callback, callback_args, callback_kwargs)
process_template_response(
self
,request,response)
process_exception(
self
, request, exception)
process_response(
self
, request, response)

process_request:

    在接到用户请求时所定义的处理函数。

process_view:

    这一步是在路由分发之后,views函数之前所执行的处理函数。

process_template_response:

    这个函数基本不用,只有当views函数返回中有render时才会执行的处理函数。

process_exception:

    异常处理函数,只有当views中函数出现异常时才会执行。其他process_xxx函数出现异常时,是不会触发此函数的。

process_response:

    response返回时执行的处理函数。

一个正常的中间件执行流程:

    首先,先从第一个中间件的process_request函数到达最后一个中间件的process_request函数,如果没有出现返回的话。紧接着又从第一个中间件的process_view函数一直执行到最后一个中间件的process_view函数,然后将请求传递给views函数处理。views函数返回时,先从最后一个中间件的process_response开始执行一直到第一个中间件的process_response函数处理完成,然后返回给用户。

    从Django1.10版本开始,当某个中间件的process_request函数触发了返回,那么在这个中间件之后的所有中间件方法都不会执行。直接从这个中间件开始向前执行process_response函数,最终返回给用户。

    Django1.10版本之前的版本是,当某个中间件的process_request函数触发了返回,那么在这个中间件之后的所有中间件的process_request方法都不会执行,但会从最后一个中间件开始向前执行process_response函数,最终返回给用户。

一个包含异常处理的中间件执行流程:

    process_exception函数只当views发生异常时才会执行,它先从最后一个中间件开始搜索异常处理方法。如果最后一个中间件没有处理,它会将异常传递给前一个中间件,如果一直传递给第一个中间件都没有处理异常。它就返回最后一个中间件开始执行process_response函数,最终返回给用户。

    如果其中某一个中间件处理了这个异常,它就会立刻返回到最后一个中间件开始执行process_response函数,在这个中间件之前的所有中间件的process_exception函数就不执行了。

四、如何自定义中间件

a、在项目中新建一个py文件

1
TestMiddleware.py

b、编辑TestMiddleware.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
from 
django.utils.deprecation 
import 
MiddlewareMixin
 
class 
TestMiddleware1(MiddlewareMixin):
    
def 
process_request(
self
, request):
        
print
(
"Test1-->process_request"
)
 
    
def 
process_response(
self
, request, response):
        
print
(
"Test1-->process_response"
)
        
return 
response
 
    
def 
process_view(
self
, request, callback, callback_args, callback_kwargs):
        
print
(
"Test1-->process_view"
)
 
 
class 
TestMiddleware2(MiddlewareMixin):
    
def 
process_request(
self
, request):
        
print
(
"Test2-->process_request"
)
 
    
def 
process_response(
self
, request, response):
        
print
(
"Test2-->process_response"
)
        
return 
response
 
    
def 
process_view(
self
, request, callback, callback_args, callback_kwargs):
        
print
(
"Test2-->process_view"
)
 
 
class 
TestMiddleware3(MiddlewareMixin):
    
def 
process_request(
self
, request):
        
print
(
"Test3-->process_request"
)
 
    
def 
process_response(
self
, request, response):
        
print
(
"Test3-->process_response"
)
        
return 
response
 
    
def 
process_view(
self
, request, callback, callback_args, callback_kwargs):
        
print
(
"Test3-->process_view"
)

    在Django1.10之前,我们自定义的中间件类继承的是Object。从Django1.10开始,我们必须继承MiddlewareMixin类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class 
MiddlewareMixin(
object
):
    
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

c、在setting.py文件添加自定义的中间件

1
2
3
4
5
6
7
8
9
10
11
12
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'
,
    
'TestMiddleware.TestMiddleware1'
,
    
'TestMiddleware.TestMiddleware2'
,
    
'TestMiddleware.TestMiddleware3'
,
]

    MIDDLEWARE是一个列表,所以里面中间件的顺序是很重要的,不能随意颠倒。为了不影响它原先的功能,我们把自定义的中间件一般放到最后执行。当然如果你做了一个IP拦截功能的中间件,你也可以把它放到第一个执行。

    我们写了这么多的process_request、process_view、process_response函数,那这些都是必须要写的的吗?答案是否定的,你想写哪个就写哪个,自定义中间件中可以写任意一个或多个函数。这些函数名是不能变的!

本文转自戴柏阳的博客博客51CTO博客,原文链接http://blog.51cto.com/daibaiyang119/1978025如需转载请自行联系原作者

daibaiyang119

你可能感兴趣的文章
react-native 模仿原生 实现下拉刷新/上拉加载更多(RefreshListView)
查看>>
MySQL出现Access denied for user ‘root’@’localhost’ (using password:YES)
查看>>
通过Roslyn构建自己的C#脚本(更新版)(转)
查看>>
红黑树
查看>>
UIImagePickerController拍照与摄像
查看>>
python调用windows api
查看>>
Linux内核中的printf实现【转】
查看>>
第四章 mybatis批量insert
查看>>
Dom4j生成xml
查看>>
Java并发框架——什么是AQS框架
查看>>
【数据库】
查看>>
从一次线上故障思考Java问题定位思路
查看>>
Win配置Apache+mod_wsgi+django环境+域名
查看>>
第四届中国汽车产业信息化技术创新峰会将于6月在沪召开
查看>>
linux清除文件内容
查看>>
WindowManager.LayoutParams 详解
查看>>
find的命令的使用和文件名的后缀
查看>>
Android的Aidl安装方法
查看>>
Linux中rc的含义
查看>>
曾鸣:区块链的春天还没有到来| 阿里内部干货
查看>>