django中间件

django中间件

还记得我们之前发送post请求的时候,会报错,都需要在发送请求之前把 settings 的中间件中的一条给注释掉。

来看一下之前的 django 请求生命周期图

img

这张图还可以这么画

img

中间件被放大了来看,我们默认的中间件有七个,我们之前都是吧第四个给注释掉。从这个图的流程来看,浏览器发送请求一直到了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方法')

img

一旦里面返回了 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 开始走。

这时候我们就可以在这些个方法里面做各种校验了

所以,“用户访问频率限制用户是否是黑名单,白名单,所有用户登录校验等等。”

只要是涉及到网址全局的功能 你就应该考虑使用中间件

下一篇博客是真正讲解注释掉的中间件的作用的。

posted @ 2019-10-30 23:23  chanyuli  阅读(122)  评论(0编辑  收藏  举报