什么是中间件?中间件的作用,怎么使用中间件及应用场景


幽默爱汽车
幽默爱汽车 2022-09-21 09:14:48 51995
分类专栏: 资讯

什么是中间件?中间件的作用,怎么使用中间件及应用场景

如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。

可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。

Django默认的中间件:(在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图)

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',
   'app01.mymid.MyMid1',
   'app01.mymid.MyMid2',
]
zE5NDYzNTY5MC00OTgxNzk0NDMucG5n?x-oss-process=image/format,png" alt="img"> 

上述截图中的中间件都是django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承MiddlewareMixin

第一步:导入

from django.utils.deprecation import MiddlewareMixin
  • 1

第二步:自定义中间件

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class Md1(MiddlewareMixin):
def process_request(self,request):
  print("Md1请求")
def process_response(self,request,response):
  print("Md1返回")
  return response

class Md2(MiddlewareMixin):
   def process_request(self,request):
       print("Md2请求")
   return HttpResponse("Md2中断")
   def process_response(self,request,response):
       print("Md2返回")
       return response
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

第三步:在view中定义一个视图函数(index)

def index(request):
   print("view函数...")
    return HttpResponse("OK")
  • 1
  • 2
  • 3

第四步:在settings.py的MIDDLEWARE里注册自己定义的中间件

img

运行结果:

Md1请求
Md2请求
view函数...
Md2返回
Md1返回
  • 1
  • 2
  • 3
  • 4
  • 5

**注意:**如果当请求到达请求2的时候直接不符合条件返回,即return HttpResponse(“Md2中断”),程序将把请求直接发给中间件2返回,然后依次返回到请求者,结果如下:

返回Md2中断的页面,后台打印如下:

Md1请求
Md2请求
Md2返回
Md1返回
  • 1
  • 2
  • 3
  • 4

流程图如下:

img

由此总结一下:

  1. 中间件的process_request方法是在执行视图函数之前执行的。
  2. 当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。
  3. 不同中间件之间传递的request都是同一个对象

多个中间件中的process_response方法是按照MIDDLEWARE中的注册顺序倒序执行的,也就是说第一个中间件的process_request方法首先执行,而它的process_response方法最后执行,最后一个中间件的process_request方法最后一个执行,它的process_response方法是最先执行。

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并返回结果。

process_view(self, request, callback, callback_args, callback_kwargs)
  • 1
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class Md1(MiddlewareMixin):

  def process_request(self,request):
      print("Md1请求")
      return HttpResponse("Md1中断")
  def process_response(self,request,response):
      print("Md1返回")
      return response

  def process_view(self, request, callback, callback_args, callback_kwargs):
      print("Md1view")


class Md2(MiddlewareMixin):

  def process_request(self,request):
       print("Md2请求")
       return HttpResponse("Md2中断")
   def process_response(self,request,response):
       print("Md2返回")
       return response

  def process_view(self, request, callback, callback_args, callback_kwargs):
       print("Md2view")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

运行结果:

Md1请求
Md2请求
Md1view
Md2view
view函数...
Md2返回
Md1返回
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

下图进行分析上面的过程:

img

当最后一个中间的process_request到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views函数,最后通过process_response依次返回到达用户。

process_view可以用来调用视图函数:

class Md1(MiddlewareMixin):

  def process_request(self,request):
      print("Md1请求")
      return HttpResponse("Md1中断")
  def process_response(self,request,response):
      print("Md1返回")
      return response

  def process_view(self, request, callback, callback_args, callback_kwargs):

       return HttpResponse("hello")

      response=callback(request,*callback_args,**callback_kwargs)
      return response
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

运行结果:

Md1请求
Md2请求
view函数...
Md2返回
Md1返回
  • 1
  • 2
  • 3
  • 4
  • 5

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

3、process_exception

process_exception(self, request, exception)

该方法两个参数:

一个HttpRequest对象

一个exception是视图函数异常产生的Exception对象。

这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。

process_exception(self, request, exception)
  • 1

实例如下:

class Md1(MiddlewareMixin):

  def process_request(self,request):
      print("Md1请求")
      return HttpResponse("Md1中断")
  def process_response(self,request,response):
      print("Md1返回")
      return response

  def process_view(self, request, callback, callback_args, callback_kwargs):

       return HttpResponse("hello")

       response=callback(request,*callback_args,**callback_kwargs)
       return response
      print("md1 process_view...")

  def process_exception(self,request,exception):
      print("md1 process_exception...")



class Md2(MiddlewareMixin):

  def process_request(self,request):
      print("Md2请求")
       return HttpResponse("Md2中断")
  def process_response(self,request,response):
       print("Md2返回")
       return response
   def process_view(self, request, callback, callback_args, callback_kwargs):
       print("md2 process_view...")

   def process_exception(self,request,exception):只有报错了才会执行exception
      print("md1 process_exception...")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

运行结果:

Md1请求
Md2请求
md1 process_view...
md2 process_view...
view函数...

Md2返回
Md1返回
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

流程图如下:

当views出现错误时:

img

将md2的process_exception修改如下:

 def process_exception(self,request,exception):

      print("md2 process_exception...")
      return HttpResponse("error")
  • 1
  • 2
  • 3
  • 4

运行结果:

Md1请求
Md2请求
md1 process_view...
md2 process_view...
view函数...
md2 process_exception...
Md2返回
Md1返回
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4、process_template_response(self,request,response)

该方法对视图函数返回值有要求,必须是一个含有render方法类的对象,才会执行此方法

class Test:
  def __init__(self,status,msg):
      self.status=status
      self.msg=msg
  def render(self):
       import json
      dic={'status':self.status,'msg':self.msg}

       return HttpResponse(json.dumps(dic))
def index(response):
   return Test(True,'测试')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

四 中间件应用场景

1、做IP访问频率限制

某些IP访问服务器的频率过高,进行拦截,比如限制每分钟不能超过20次。

2、URL访问过滤

如果用户访问的是login视图(放过)

如果访问其他视图,需要检测是不是有session认证,已经有了放行,没有返回login,这样就省得在多个视图函数上写装饰器了!

作为延伸扩展内容,有余力的同学可以尝试着读一下以下两个自带的中间件:

'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
  • 1
  • 2

文章知识点与官方知识档案匹配,可进一步学习相关知识
Python入门技能树Web应用开发 Django127519 人正在系统学习中

网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

本文链接:https://www.xckfsq.com/news/show.html?id=8708
赞同 0
评论 0 条
幽默爱汽车L0
粉丝 0 发表 13 + 关注 私信
上周热门
如何使用 StarRocks 管理和优化数据湖中的数据?  2941
【软件正版化】软件正版化工作要点  2860
统信UOS试玩黑神话:悟空  2819
信刻光盘安全隔离与信息交换系统  2712
镜舟科技与中启乘数科技达成战略合作,共筑数据服务新生态  1246
grub引导程序无法找到指定设备和分区  1213
华为全联接大会2024丨软通动力分论坛精彩议程抢先看!  163
点击报名 | 京东2025校招进校行程预告  162
2024海洋能源产业融合发展论坛暨博览会同期活动-海洋能源与数字化智能化论坛成功举办  160
华为纯血鸿蒙正式版9月底见!但Mate 70的内情还得接着挖...  157
本周热议
我的信创开放社区兼职赚钱历程 40
今天你签到了吗? 27
信创开放社区邀请他人注册的具体步骤如下 15
如何玩转信创开放社区—从小白进阶到专家 15
方德桌面操作系统 14
我有15积分有什么用? 13
用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
如何让你先人一步获得悬赏问题信息?(创作者必看) 12
2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

加入交流群

请使用微信扫一扫!