Django中间件


一般Django处理流程:

用户请求--->路由(urls)匹配--->找视图函数(views) 取数据 拿模板(templates) --->渲染--->然后把字符串返回给用户

在路由匹配之前还要经过中间件的处理:

中间件里面有很多"管道"

其实是不同的类,各个类中有很多方法,各方法处理不同的情况

比如进来的时候依次执行类A的方法1--->-类B的方法1-->类C的方法1.......

出去的时候依次执行各类的方法2等等

中间件在settings里面

中间件应用:设置黑名单、登录验证(规定一些不用登录的界面,登录过的不同登录,没有登录过的访问的话需要返回到登录界面)、

自己写一个中间件

方法:参考人家的中间件,看看里面都有什么方法

 模仿写两个中间件来查看执行轨迹

 1 #这是中间件
 2 from django.utils.deprecation import MiddlewareMixin
 3 from django.shortcuts import HttpResponse
 4 
 5 class C1(MiddlewareMixin):
 6     def process_request(self,request):
 7         # 这里不要轻易加返回值return(Django内部会自动传递),不然有了返回值后面的中间件就不执行
 8 
 9         #return HttpResponse('c1return')
10         #端口会直接返回  后面的request就没办法搞了,直接执行自己的response
11         #Django1.8以前的会跳到最后一个类执行response
12         print('C1已经执行request')
13 
14     def process_view(self, request, callback, callback_args, callback_kwargs):
15         #print('_view里面的',callback视图函数,做路由匹配到对应函数, callback_args, callback_kwargs)
16         print('C1已经执行_view')
17         #view执行完才执行视图函数里面的内容
18         
19         #response=callback(request,*callback_args,**callback_kwargs)
20         #return response
21         #若是这里返回了,后面的process_view就不会执行了
22         #直接跳到执行视图函数,然后从下往上,依次把所有的response执行一遍
23     def process_response(self, request, response):
24         print('C1已经执行response')
25         return response
26         #这里一定要加返回值,因为是一个个传递的,如果不加会中断传递,会报错
27 
28     def process_exception(self, request, exception):
29          print('C1已经执行exception')
30          return HttpResponse('错误啦,是么')
31          #报错的话不会执行视图函数,会执行这个异常HttpResponse(属于返回,在response之前执行)
32     def process_template_response(self,request,response):
33         print('C1已经执行template')
34         #视图函数的返回值中,有render方法 才被调用 。可触发类里面的render方法(封装特定的方法为对象,方便调用)
35         #比如  多出需要返回给前端JSON,就要写多遍,通过类封装后,遇到情况一样的直接建立对象(调用)操作就行
36         #自动处理类里面的render方法
37         return response
38 
39 class C2(MiddlewareMixin):
40     def process_request(self,request):
41         print('C2已经执行request')
42     def process_view(self, request, callback, callback_args, callback_kwargs):
43         print('C2已经执行_view')
44 
45     def process_response(self, request, response):
46         print('C2已经执行response')
47         return response
48        #这里一定要加返回值,因为是一个个传递的,如果不加会中断传递,会报错
49     def process_exception(self, request, exception):
50          print('C2已经执行exception')
51          return HttpResponse('错误啦')
52          #由下到上检测执行exception,一旦有一个执行完成,后面的exception就全部跳过,去执行response
53     def process_template_response(self, request, response):
54         print('C2已经执行template')
55         return response

settings里面把写在mb.py的两个类加进去

MIDDLEWARE = [  #这些都是中间件
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
   # 'django.middleware.csrf.CsrfViewMiddleware',  #csrf
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'mb.C1',
    'mb.C2',
]

相关视图函数

 1 class Foo:## 自定义中间件最后一个方法用这个
 2     def __init__(self,request,status,msg):
 3         self.request=request
 4         self.status=status
 5         self.msg=msg
 6 
 7     def render(self):
 8         #一些处理操作
 9           return HttpResponse('ok')
10 
11 def test616(request):
12 
13     #自定义中间件前四种方法用这个
14     # print('********')
15     # return HttpResponse('*******')
16 
17     # 自定义中间件最后一个方法用这个
18     return Foo(request,True,'错误信息')

正常执行:request(1、2)、view1(1,2)、response(2,1)

有报错执行(假设只有2报错):request(1、2)、view1(1,2)、exception(2)、response(2,1)

有render方法被执行:request(1、2)、view1(1,2)、template(2,1)、exception(2)、response(2,1)

 传送门