day21-Django中间件
一、前言
我们今天来学习一下django的中间件,这个东西呢,还是比较重要的,我们之间就在settings的文件中注释掉 csrf的插件(#django.middleware.csrf.CsrfViewMiddleware),那在setting文件中MIDDLEWARE中还有其他的中间件,他们是干嘛的呐?今天我们就来学习一下。我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下,也就是中间件的原理图:
django的中间件,在settings.py文件中,如下:
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', ]
二、自定义中间件
我们知道其实每个中间件都是类里面的方法,所以我们添加中间的时候,需要自定义一个类,把这个类,导入到settings.py文件中的MIDDLEWARE中,好吧,接下来我们来完整搞一个自定义中间件。
2.1、继承类MiddlewareMixin
说明:在项目下创建一个Middle一个文件夹,然后随便创建一个py文件,在这个py文件创建类,这个类一定要继承MiddlewareMixin这个类,所有的中间件都是继承这个类的。
如果想知道其他中间件是否继承这个类,就我们在setting文件里面的中间中随便找一个中间件,然后导入一下,再 ctrl + 类名 进去看看源码:
我们继续往下看:
果然是继承这个MiddlewareMixin这个类,继续 Cttrl+类名 看源码,这个类的源码如下:
class MiddlewareMixin: def __init__(self, get_response=None): self.get_response = get_response super().__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
所以我们自定义类满足以下条件:
- 自定义类需要继承MiddlewareMixin类
- 需要重写process_request和process_response函数
- 需要导入到settings.py文件中的MIDDLEWARE中,到类级别
2.2、自定义中间件类
说明:我们创建好自己的文件夹之后,又知道所有的中间件是继承 MiddlewareMixin 类,所以我们自定义的类必须继承 MiddlewareMixin 类,所以m1.py文件如下:
class Row1(MiddlewareMixin): def process_request(self,request): print("傻逼鸿....") def process_response(self,request,response): print("kangbazi") return response from django.shortcuts import HttpResponse class Row2(MiddlewareMixin): #这边的request跟view函数的request是一样的,有对应的post,get方法 def process_request(self,request): print("鸿哥哥是傻逼....") #return HttpResponse("扯犊子....") #失败的情况下才会需要返回值,成功的情况下不需要写返回值 def process_response(self,request,response): print("shabihong....") return response #这边需要做返回页面处理,如果不做处理,页面会报错
我们定义好了之后,要在setting.py文件中间件,导入自定义的中间件:
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', 'Middle.m1.Row1', #导入的时候,需要导入到类级别 'Middle.m1.Row2', ]
在view.py中设置测试test的代码:
def test(request): print("呆逼鸿------>没钱了") return HttpResponse("ok")
正常输出如图所示:
但是如果我们遇到一些不正常的请求呐,就是说在process_request中有return函数的话,就原理就如下图,这个图有请求正确和请求不正确的情况:
注意了:
正常请求:process_request中没有return返回值 不正常的请求:process_request中,有return返回值 还有就是:process_request和process_response的函数名不能变,都是这么定义的
三、django中间件补充
上面我们已经用到process_request和process_response,但是除了这几个还有其他的几个,还有一个比较经常用,另外两个不经常用,所以中间件中定义了4个方法,分别是:
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)
以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。
3.1、process_view
说明:当完全执行完process_request之后就会去执行process_view这个函数
def process_view(self, request, view_func, view_func_args, view_func_kwargs): print("高哥哥") #view_func 指的是view函数 #view_func_args:当url的参数里面不是name定义的,就直接是'test/(\d+)'定义的,用这个接收 #view_func_kwargs ,当url里面是name定义的,是'test/(?P<nid>\d+)'定义的,用这个接收
如图:
输出的结果:
傻逼鸿.... 鸿哥哥是傻逼.... gaogege.... 高哥哥 呆逼鸿------>没钱了 shabihong.... kangbazi
所以执行图是这样的:
3.2、process_exception
说明:如果view函数报错了,这个东西才会执行,否则不会执行。
def process_exception(self,request,exception): print('ex')
这个东西不经常用,所以暂时咋不说,知道就行了。
如图:
3.3、process_template_response
说明:如果view函数返回的对象中,具有render方法,这个函数才会执行,这个东西也用不到,知道就行。
def process_template_response(self,request,response): print("----------") return response #继续请求下去,就要把返回值返回了
如图:
四、总结
- 中间件的作用:判断一下,客户端发来的请求有没有带那个请求头,如果带那个请求头,它说你不要再继续往下走了,在我这边就直接终止掉了,这个适合所有请求统一操作,公共校验,黑名单过滤就在中间件这边过滤了。
- 定义中间件的类必须继承MiddlewareMixin,并且需要在setting.py文件中导入,导入的时候到类级别即可。
- 定义的类,需要重写process_request、process_view和process_response方法,因为这三个是经常用到的,另外两个不经常用到。