django中间件详解

中间件定义:

中间件就是在目标结果之间进行的额外处理过程,在Django中就是request和response之间进行的处理,相对来说实现起来比较简单,但是要注意它是对全局有效的,可以在全局范围内改变输入和输出结果,因此需要谨慎使用,否则不仅会造成难以定位的错误,而且可能会影响整体性能。

 
中间件作用:

需要全局配合request和response实现的功能,可以在中间件过程中实现,比如:

  • 登陆认证:在中间件中加入登陆认证,所有请求就自动拥有登陆认证,如果需要放开部分路由,只需要特殊处理就可以了。

  • 流量统计:可以针对一些渲染页面统计访问流量。

  • 恶意请求拦截:统计IP请求次数,可以进行频次限制或者封禁IP。

 
中间件执行流程:

django中原生七大中间件

复制代码
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',
]
复制代码

每个中间件都是一个类,多个中间件可以写在同一个文件中,也可以独立文件,每个中间件包含五个方法:

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)

执行流程:

  • 请求到达中间件后先依次执行每个中间件的process_request函数

  • 然后再依次执行每个中间件的process_view函数,找到我们的视图函数

  • 执行视图函数处理请求数据

  • 如果在上面的过程中出现异常,则依次反方向执行每个中间件的process_exception函数

  • 如果请求包含模板渲染,则依次反方向执行每个中间件的process_template_response函数

  • 最后依次反方向执行每个中间件的process_response函数

以上这些执行函数将返回None或者HttpResponse对象,如果返回None,则交给下一个中间件的对应函数处理;如果返回HttpResponse对象,则将其返回给用户.

在这些中间件的执行函数中,我们最常用的就是process_request和process_response函数,通常用来在视图函数处理前和视图函数处理后执行一些相应的操作,这个要根据我们的业务需求,选择不同的处理过程。例如:进行登陆认证,因为必须要在视图函数处理前进行认证,我们可以在process_request中处理;携带认证cookies信息,就可以在process_response函数中给response对象增加指定cookies值。

 
#  请求到达中间件之后,先按照正序执行每个注册中间件的process_reques方法,process_request方法返回的值是None,就依次执行,如果返回的值是HttpResponse对象,不再执行后面的process_request方法,而是执行当前对应中间件的process_response方法,将HttpResponse对象返回给浏览器。也就是说:如果MIDDLEWARE中注册了6个中间件,执行过程中,第3个中间件返回了一个HttpResponse对象,那么第4,5,6中间件的process_request和process_response方法都不执行,顺序执行3,2,1中间件的process_response方法。

 

 

    # process_request方法都执行完后,匹配路由,找到要执行的视图函数,先不执行视图函数,先执行中间件中的process_view方法,process_view方法返回None,继续按顺序执行,所有process_view方法执行完后执行视图函数。假如中间件3 的process_view方法返回了HttpResponse对象,则4,5,6的process_view以及视图函数都不执行,直接从最后一个中间件,也就是中间件6的process_response方法开始倒序执行。

 

# process_template_response和process_exception两个方法的触发是有条件的,执行顺序也是倒序。

 

 

中间件回调函数执行:

  • Request函数:process_request(self, request) 执行时机:当接收到前端请求,并生成request对象,但是仍未解析url,未确定当前要运行的视图函数。 如果返回None,Django将继续处理下一个中间件的request函数;如果返回HttpResponse对象,Django将不再执行其他除process_response以外的所有函数,包括后面的process_request函数其他中间件函数以及视图函数

  • View函数:process_view(self, request, callback, callback_args, callback_kwargs)执行时机:在执行完所有中间件的process_request函数,并且已经匹配到要执行的视图函数,但是还没有调用视图函数之前。 callback:要执行的视图函数对象(就是我们所写的视图处理函数) callback_args:视图函数的位置参数列表(不包含self和request) callback_kwargs:视图函数的关键字参数 如果返回None,Django将继续处理下一个中间件的view函数;如果返回HttpResponse对象,Django将不再执行其他除process_response以外的所有函数,包括后面的process_request函数其他中间件函数以及视图函数

  • Template函数:process_template_response(self, request, response) 执行时机:只有在视图函数的返回对象中有render方法才会执行,并把render方法的返回值返回给用户。

  • Exception函数:process_exception(self, request, exception) 执行时机:如果在执行过程中出现问题,并且抛出一个未被捕获的异常时才被调用。我们可以用它来捕获请求错误,发送通知或者恢复错误场景。 如果返回None,Django将使用框架内置异常处理,并继续交给下一个exception函数;如果返回HttpResponse对象,Django将不再执行其他除process_response以外的所有函数,并中断异常处理。

  • Response函数:process_response(self, request, response) 执行时机:执行完view函数并生成response之后,几乎是必执行的函数。 返回并且只能必须返回HttpResponse对象,否则会导致HTTP请求中断。

 

自定义中间件:

待补充

 

 

 

 

 

 

 

 

posted @   EricYJChung  阅读(277)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示