django中间件
django中间件
还记得我们之前发送post请求的时候,会报错,都需要在发送请求之前把 settings 的中间件中的一条给注释掉。
来看一下之前的 django 请求生命周期图
这张图还可以这么画
中间件被放大了来看,我们默认的中间件有七个,我们之前都是吧第四个给注释掉。从这个图的流程来看,浏览器发送请求一直到了django中间件这里,以此满足每一个中间件,然后才能进入路由层,最后出来的时候也要经过每一个中间件,这次的顺序是反着来。只要这过程中有一个中间件不满足,给你拦下了,那么你的请求都会失败。
所以这意味着,我们可以自己来写中间件,用来做一些全局的筛选。
首先搞清楚一些需要我们知道的中间件的功能。
'django.contrib.sessions.middleware.SessionMiddleware',
顾名思义,这就是跟session有关的了,我们上一篇博客中的,“浏览器发送cookie到django后端之后,django会自动获取到cookie的值,然后拿着随机字符串去表中比对”,就是这个中间件干的。以及,设置session的时候,request.session['key'] = value只是在内存中产生一个缓存,真正的写入数据库的操作是走到这个中间件的时候,在这个中间件中完成的操作。
为了搞清楚中间件里面都干了些什么,看一下源码。
发现里面都有两个共同的方法。
django中间件暴露给程序员五个可以自定义的方法(五个方法都是在特定的条件下自动触发的)
需要掌握的
process_request(******):
请求来的时候 会从上往下依次经过每一个中间件里面process_request,一旦里面返回了HttpResponse对象那么就不再往后执行了 会执行同一级别的process_response
def process_request(self,request):
print('我是第一个自定义中间件里面的process_request方法')
return HttpResponse("我是第一个自定义中间件里面的HttpResponse对象返回值") # 直接原地返回
process_response(***):
响应走的时候 会从下往上依次进过每一个中间件里面的process_response
def process_response(self,request,response): # response就是要返回给用户的数据
print("我是第一个自定义中间件里面的process_response方法")
return response
了解即可的,最好能说出来
process_view:路由匹配成功之后执行视图函数之前触发
process_exception:当视图函数出现异常(bug)的时候自动触发
process_template_response:当视图函数执行完毕之后并且返回的对象中含有render方法的情况下才会触发
要如何来自定义这些方法呢?
1.新建一个文件夹 里面新建一个任意名称的py文件
里面写类 固定继承
from django.utils.deprecation import MiddlewareMixin
class MyMiddle(MiddlewareMixin):
...
2.去配置文件注册到中间件配置中
你需要手写字符串的路径
'app01.mymiddleware.myaabb.MyMiddle1'
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class My_Middle(MiddlewareMixin):
def process_request(self,request):
print(request.POST.get('username'))
print('我是第一个自定义中间件里面的process_request方法')
class My_Middle1(MiddlewareMixin):
def process_request(self,request):
print(request.POST.get('username'))
print('我是第2个自定义中间件里面的process_request方法')
一旦里面返回了 HTTPResponse 对象,就会直接返回,不往下走了,比如下面的代码
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class My_Middle(MiddlewareMixin):
def process_request(self,request):
print(request.POST.get('username'))
print('我是第一个自定义中间件里面的process_request方法')
return HttpResponse("我是第一个自定义中间件里面的HttpResponse对象返回值")
class My_Middle1(MiddlewareMixin):
def process_request(self,request):
print(request.POST.get('username'))
print('我是第2个自定义中间件里面的process_request方法')
然后讲一下 process.response,只要是这个方法,一定要接受一个response参数,一并且定要返回response。
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class My_Middle(MiddlewareMixin):
def process_request(self,request):
print(request.POST.get('username'))
print('我是第一个自定义中间件里面的process_request方法')
# return HttpResponse("我是第一个自定义中间件里面的HttpResponse对象返回值")
def process_response(self, request, response): # response就是要返回给用户的数据
print("我是第一个自定义中间件里面的process_response方法")
return response
class My_Middle1(MiddlewareMixin):
def process_request(self,request):
print(request.POST.get('username'))
print('我是第2个自定义中间件里面的process_request方法')
def process_response(self, request, response): # response就是要返回给用户的数据
print("我是第二个自定义中间件里面的process_response方法")
return response
每一个中间件的process_response方法都要返回response,这是返回时候的路线,所以是从下面往上走,会想打印"我是第二个自定义中间件里面的process_response方法",然后在打印"我是第一个自定义中间件里面的process_response方法"。
当我们在第一个自定义中间件的process_request方法中直接返回了一个HttpResponse对象, 他就不会往下走了,直接走同级别的 process_response方法,和其他框架不太一样,比如flask,flask就会从最下面的中间件的 process_response 开始走。
这时候我们就可以在这些个方法里面做各种校验了
所以,“用户访问频率限制用户是否是黑名单,白名单,所有用户登录校验等等。”
只要是涉及到网址全局的功能 你就应该考虑使用中间件
下一篇博客是真正讲解注释掉的中间件的作用的。