Django学习之中间件

1>概念

    中间件,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入

    与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。

    比如你想修改请求,例如被传送到view中的HttpRequest对象,或者修改view返回的HttpResponse对象,可能

    你还想在view执行之前做一些操作,这些都可以通过中间件来实现。

2>中间件的四个方法

  process_request

  process_view

  process_exception

  process_response

    当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求是process_request,最后到达views的函数中,

    views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者

    我们也可以自己写一个中间件,这个类必须继承MiddlewareMixin

 from django.utils.deprecation import MiddlewareMixin

    Django学习之中间件

 Django学习之中间件

   上面就是正常情况下,中间件的执行过程,如上,它会按至上而下的顺序依次执行各个中间件的process_request函数,

    到视图函数,返回响应时就 至下而上执行中间件的 process_response,注意函数的传参,

    注意中间件类并不一定非要process_response函数,但如果定义了这个函数,就必须加上返回值,一般是直接

   return response,这个response就是视图函数的返回值,当然,也可以自己写返回值,这样,就会替换之前视图函数的

   返回值。(这就类似一个接力棒赛跑,因视图函数执行完是一定有返回值的,所以,若中间件写了对应函数,就必须接收,

   这样,下一个中间件再接收传递,直到返回给请求体,若中间件写了process_response但是不加返回值,接力棒就会断在

   这里,最终送不到请求体而报错。)

    如果在process_request加上返回值,会怎样?如下。

Django学习之中间件

所以,当process_request有返回值,类似于这里就产生了“接力棒”,程序就不往下走了,之后的中间件及视图函数就

不再执行,而是当即“原路返回”,整个流程图如下,

Django学习之中间件

3>process_view

Django学习之中间件

Django学习之中间件

当最后一个中间的process_request到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views

函数,最后通过process_response依次返回到达用户

Django学习之中间件

注意:process_view如果有返回值,会越过其他的process_view以及视图函数,但是所有的process_response都还会执行

4>process_exception

Django学习之中间件

Django学习之中间件

Django学习之中间件

5>中间件应用例子,改写下之前的登陆认证

   试想如下场景,服务器有100个path,有80个都需要登录验证,如果每个视图函数都加装饰器,也挺繁琐的,这个时候,

我们可以通过中间件来实现,就很轻松了,如下,之前认证例子改写如下:

Django学习之中间件

Django学习之中间件

实现效果跟之前加装饰器一样,

注意:中间件的使用需结合实际场景,因为这个配置时全局性的,使用不当则影响性能,试想一下,上面的认证例子,

如果该服务器有100个path,但是需认证的是有10个,那还需要中间件做认证吗?------这个时候加几个装饰器就解决了,

就没必要用啦,因为大部分path都不必认证,如果加了中间件,那这些path每次访问都会执行认证代码,岂不是影响性能。