Django——中间件及用法
1.django内置中间件
# 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能 # django内置中间件 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',#注释之后就拿不到request.session了 'django.middleware.common.CommonMiddleware',#重定向 'django.middleware.csrf.CsrfViewMiddleware',#注释之后发post请求会被禁止 'django.contrib.auth.middleware.AuthenticationMiddleware',#如果'django.contrib.sessions.middleware.SessionMiddleware'注释了,那这个也要注释,不然会报错 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
2.自定义中间件
1 自定义步骤: -写一个类,继承MiddlewareMixin -里面写方法process_request(请求来了,一定会触发它的执行) -在setting中配置(注意,放在前和放在后) MIDDLEWARE = [ ... 'app01.mymiddle.MyMiddleware1', ... ]
3.自定义中间件 代码
#settings.py 略 #urls.py 略 #mymiddle.py from django.utils.deprecation import MiddlewareMixin from django.shortcuts import render,HttpResponse class MyMiddleware1(MiddlewareMixin): # 所有的请求来了,都会走到它 def process_request(self,request): # request就是当请求的request对象 print('请求来了') # 所有的请求走了,都会执行它 def process_response(self, request, response): print('请求走了') return response #views.py from django.shortcuts import render,HttpResponse,redirect def index(request): print('我是视图函数') return HttpResponse('ok')
4.中间件需要知道的用法
process_request,process_response,process_view,process_exception
1 process_request(request对象) 2 process_response(request对象,response对象) ''' 如这个网址:127.0.0.1/user/... 加cookie name=lili 利用process_request 和process_response 因为已经有request对象了,先用request.get_full_path()取到所有路径, 判断路径如果是127.0.0.1/user/...就加上cookie,用reponse.set_cookie('name','lili')不是就不做处理 ''' 3 多个中间件,执行顺序是什么?(!!!记得写好中间件) -请求来的时候从上往下执行:process_request -请求走的时候,从下往上执行:process_response 4 process_request可以干什么? -写一个中间件,不管前端用什么编码,在requset.data中都有post的数据 -频率限制(限制某个ip地址,一分钟只能访问5次) -登录认证(只要没登录,重定向到login路径)、 -记录用户访问日志(ip,时间,访问路径) 5 process_response可以干什么?内部有response对象 -统一给所有(某几个路径)加cookie -统一给所有(某几个路径)加响应头 6 process_view 路由匹配成功和视图函数执行之前执行(callback就是视图函数) def process_view(self, request, callback, callback_args, callback_kwargs): # print(callback) # print(callback_args) # print(callback_kwargs) # res=callback(request) # print("中间件1的process_view") return res 7 process_exception 视图函数出错,会执行它(全局异常捕获)(可以记录日志,哪个ip地址,访问哪个路径出的错,利用request对象) # 全局异常捕获,返回4开头的 def process_exception(self, request, exception): print(exception) return render(request,'error.html') 8 process_template_response(self,request,response) 该方法对视图函数的返回值有要求,必须是一个含有render方法类的对象,才会执行此方法
5.用法中3的代码
#urls.py urlpatterns = [ path('', views.index), ] #index.html 创建一个index.html就行 #settings.py MIDDLEWARE = [ ... 'app01.mymiddle.MyMiddleware1', 'app01.mymiddle.MyMiddleware2', ... ] #mymiddle.py from django.utils.deprecation import MiddlewareMixin from django.shortcuts import render,HttpResponse class MyMiddleware1(MiddlewareMixin): # 所有的请求来了,都会走到它 def process_request(self,request): # request就是当请求的request对象 print('请求来了1') # print(request.session) # 可不可以返回?必须返回HttpResponse的对象 # return HttpResponse('我不让你访问') # 所有的请求走了,都会执行它 def process_response(self, request, response): print('请求走了1') return response #必须返回 class MyMiddleware2(MiddlewareMixin): # 所有的请求来了,都会走到它 def process_request(self,request): # request就是当请求的request对象 print('请求来了2') # print(request.session) # 可不可以返回?可以返回,但是视图函数就不走了 # return HttpResponse('dsb') # 所有的请求走了,都会执行它 def process_response(self, request, response): print('请求走了2') return response #views.py from django.shortcuts import HttpResponse def index(request): print('我是视图函数') return HttpResponse('ok')
6.用法中6的代码
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import render,HttpResponse class MyMiddleware1(MiddlewareMixin): # 所有的请求来了,都会走到它 def process_request(self,request): # request就是当请求的request对象 print('请求来了1') # print(request.session) # 可不可以返回?必须返回HttpResponse的对象 # return HttpResponse('我不让你访问') # 所有的请求走了,都会执行它 def process_response(self, request, response): print('请求走了1') return response # 路由匹配成功,视图函数执行之前执行 def process_view(self, request, callback, callback_args, callback_kwargs): # print(callback) #指的就是视图函数 # print(callback_args) #() # print(callback_kwargs)#{} #相当于视图函数装饰器 res=callback(request) return res ,写上它,执行顺序会变,会先执行视图函数,再执行。不加它先执行这里再 执行 视图函数 # res=callback(request) # print("中间件1的process_view") # return res class MyMiddleware2(MiddlewareMixin): # 所有的请求来了,都会走到它 def process_request(self,request): # request就是当请求的request对象 print('请求来了2') # print(request.session) # 可不可以返回? # return HttpResponse('dsb') # 所有的请求走了,都会执行它 def process_response(self, request, response): print('请求走了2') return response ''' 执行顺序: 请求来了1 请求来了2 中间件1的process_view 我是视图函数 请求走了2 请求走了1 加上call_back 执行顺序: 请求来了1 请求来了2 我是视图函数 中间件1的process_view 请求走了2 请求走了1 '''
7.用法中7的代码
#views.py from django.shortcuts import render, HttpResponse, redirect def index(request): print('我是视图函数') a return HttpResponse('ok') #error.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 404 </body> </html> #mymiddle.py from django.utils.deprecation import MiddlewareMixin from django.shortcuts import render,HttpResponse class MyMiddleware1(MiddlewareMixin): # 所有的请求来了,都会走到它 def process_request(self,request): # request就是当请求的request对象 print('请求来了1') # 所有的请求走了,都会执行它 def process_response(self, request, response): print('请求走了1') return response # 路由匹配成功,视图函数执行之前执行 def process_view(self, request, callback, callback_args, callback_kwargs): print("中间件1的process_view") class MyMiddleware2(MiddlewareMixin): # 所有的请求来了,都会走到它 def process_request(self,request): # request就是当请求的request对象 print('请求来了2') # 所有的请求走了,都会执行它 def process_response(self, request, response): print('请求走了2') return response # 全局异常捕获,返回4开头的报错信息(可以让用户觉得自己错误,而不是服务器内部错误) def process_exception(self, request, exception): print(exception) # name 'a' is not defined print('exception') #exception return render(request,'error.html') ''' 执行顺序: 请求来了1 请求来了2 中间件1的process_view 我是视图函数 name 'a' is not defined exception 请求走了2 请求走了1 '''