一、什么是中间件
中间件,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。
![a03e1c2f15e982dee923eab6e56f7df0.png](https://img-blog.csdnimg.cn/img_convert/a03e1c2f15e982dee923eab6e56f7df0.png)
django中间价官网定义:
Middleware is a framework of hooks into Django’s request/response processing.
It’s a light, low-level “plugin” system for globally altering Django’s input or output.
二、中间件有什么作用
如果你想修改请求。
例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。
可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。
Django默认的中间件:(在django项目的settings模块中,有一个 MIDDLEWARE变量,其中每一个元素就是一个中间件,如下图)
![3d4748b8f75703a608d763eaad2be8a0.png](https://img-blog.csdnimg.cn/img_convert/3d4748b8f75703a608d763eaad2be8a0.png)
请求进来是自上而下,通过反射找到类,用for循环来执行。
可以自定义中间件,但是也要写在MIDDLEWARE中,可以在app01下创建一个mymid.py文件来写我们自定义的中间件
每一个中间件都有具体的功能.
三、自定义中间件
中间件可以定义五个方法,分别是:(主要的是process_request和process_response)
1、process_request(self,request)
2、process_view(self, request, callback, callback_args, callback_kwargs)
3、process_template_response(self,request,response)
4、process_exception(self, request, exception)
5、process_response(self, request, response)
以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。
1、process_request和process_response
当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者。
![127efe3437722c651362b07c71a74357.png](https://img-blog.csdnimg.cn/img_convert/127efe3437722c651362b07c71a74357.png)
上述截图中的中间件都是django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承MiddlewareMixin。
2、process_view
process_view(self, request, view_func, view_args, view_kwargs)
该方法有四个参数:
request是HttpRequest对象。
view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称作为字符串。)
view_args是将传递给视图的位置参数的列表(无名分组分过来的值).
view_kwargs是将传递给视图的关键字参数的字典(有名分组分过来的值)。 view_args和view_kwargs都不包含第一个视图参数(request)。
Django会在调用视图函数之前调用process_view方法。
它应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,Django不会调用适当的视图函数。 它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。
3、process_exception
process_exception(self, request, exception)
该方法两个参数:
一个HttpRequest对象
一个exception是视图函数异常产生的Exception对象。
这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。
4、process_template_response(self,request,response)
该方法对视图函数返回值有要求,必须是一个含有render方法类的对象,才会执行此方法。
如何自定义中间件?
自定义中间件的模板
def
根据代码:需要定义一个中间件的工厂函数 simple_middleware,然后返回一个可以被调用的中间件 middleware
中间件工厂函数 simple_middleware 需要接收一个可以调用的 get_response 对象
返回的中间件也是一个可以被调用的对象,并且像视图一样需要接收一个request对象参数,返回一个response对象。
例如:在一个模块中新建一个middleware.py文件
在文件中写入以下代码:
![f818521e5eea278af85fcfc7c5e76fae.png](https://img-blog.csdnimg.cn/img_convert/f818521e5eea278af85fcfc7c5e76fae.png)
定义好中间件后,需要在settings.py 文件中添加注册中间件
![c7f638a5a1dbbc5ea22bb59292a24a1c.png](https://img-blog.csdnimg.cn/img_convert/c7f638a5a1dbbc5ea22bb59292a24a1c.png)
定义一个视图进行测试
![c807936b23a0818e7b4c115220226d09.png](https://img-blog.csdnimg.cn/img_convert/c807936b23a0818e7b4c115220226d09.png)
![490ae895bcbf785b2e594264f09c814b.png](https://img-blog.csdnimg.cn/img_convert/490ae895bcbf785b2e594264f09c814b.png)
四、中间件应用场景
1、做IP访问频率限制
某些IP访问服务器的频率过高,进行拦截,比如限制每分钟不能超过20次。
2、URL访问过滤
如果用户访问的是login视图(放过)
如果访问其他视图,需要检测是不是有session认证,已经有了放行,没有返回login,这样就省得在多个视图函数上写装饰器了!
3、缓存(还记得CDN吗?)
客户端请求来了,中间件去缓存看看有没有数据,有直接返回给用户,没有再去逻辑层 执行视图函数