django7.2 中间件

django 中间件

  1. 定义:是Django请求和响应处理的钩子框架。它是一个轻量级的、低级的“插件系统”,用于全局改变Django的输入(请求)或输出(响应)。下面是举例理解:

    • 浏览器发送一个请求到达Django之后,django内部是MTV的结构,在这个结构里面,这个中间件会附嵌在某个环节之上,当请求达到这个环节的时候,优先执行这个中间件。比如说,请求进到django之前得先进到主路由,在请求进入主路由之前,有一个中间件,就“钩”在主路由上,这个请求能不能到达主路由,得看这个中间件让不让,有点像高速上的收费站,要是符合要求,这个请求就可以继续往后走
    • 进入主路由之后就是进视图函数,如果在请求达到视图之前,有一个中间件“钩”在视图这,这个请求能不能达到视图也取决于这个中间件的检测
    • django处理完请求,给浏览器响应的时候,也可以有个中间件进行中间的检查
    • 比如说响应给回浏览器之前,可以用中间件过滤这些响应,例如新闻类的网站过滤敏感词汇
    • 请求进来,可以在中间件中进行次数的统计,比如说检测恶意脚本的不合法登录,数量超过xx次之后,这个请求就不让进来了
  2. 编写中间件:
      在django中,中间件以类的形式体现。一个特定的类就是一个中间件。每个中间件组件负责做一些特定的功能。
      中间件类必须继承自django.utils.deprecation.MiddlewareMixin类。
      中间件类须实现下列五个方法中的一个或多个:(这些方法会被django在某些特殊的情况下自动调用)

    1. process_request(self,request):django接到请求并在到达主路由之前(执行路由之前)被调用,在每个请求上调用,返回None(可以继续往后到路由)或HttpResponse对象(到这就戛然而止了)。适合做请求的过滤。

    2. process_view(self,request,callback,callback_args,callback_kwargs):callback是当前请求的路由对应的视图函数,callback_args和callback_kwargs是这个视图函数的位置传参和关键字传参调用。这个方法在调用视图之前被调用(当这个请求通过了process_request,紧接着就得去视图了,达到视图之前,Django调用这个方法,相当于达到视图之前的一层过滤)。返回None(可以继续往后到视图)或HttpResponse对象(这个请求到这就戛然而止了),也是个拦截操作。有些参数想替换掉,可以在这个环节做,因为能拿到视图的参数。

    3. process_response(self,request,response): 所有响应返回浏览器之前被调用,在每个请求上调用,返回值是一个HttpResponse对象,参数中的response实际上就是视图中return的那个。如果没有特殊的要求,可以直接return 参数里的response。

    4. process_exception(self,request,exception): 当处理过程中抛出异常时调用(视图函数中只要抛错了,就执行这个中间件),返回的是一个HttpResponse对象。(统一抓视图函数中的异常)

    5. process_template_response(self,request,response):在视图函数执行完毕且试图返回的对象中包含render方法时被调用,该方法需要返回实现了render方法的响应对象。

      注:中间件中的大多数方法在返回None时表示忽略当前操作进入下一项事件,当返回HttpResponse对象时表示此请求结束,直接返回给客户端。

  3. 注册中间件:写完了中间件之后,需要在settings.py中的MIDDLEWARE中注册自定义的中间件。
      配置为数组,中间件被调用时以“先上到下”再“由下到上”的顺序调用。在进入视图函数之前,都是按照类的注册顺序执行的。从视图函数中出来之后,就是按照由下至上的注册顺序调用的。

  4. 练习:用中间件实现强制某个ip地址只能向/test开头的地址发送至多五次请求。
      request.META[‘REMOTE_ADDR’]可以得到远程客户端的IP地址。
       request.path_info可以得到客户端访问的请求路由信息。

    新建一个mymiddleware.py文件,在其中编写中间件的类:

    class VisitLimit(MiddlewareMixin):
    
        #定义个类属性来存访问的次数
        visit_times = {}
    
        def process_request(self,request):
    
            #获取访问者的ip和路由
            ip_address = request.META['REMOTE_ADDR']
            path_url = request.path_info
    
            #进行匹配,只有访问/test开头的,才有必要去计数、过滤
            #拿正则匹配路由
            #如果不是/test开头的,就return None,表示这个请求可以继续往下走
            if not re.match('^/test',path_url):
                return None
    
            #用get取当前ip地址访问的次数,因为get方法有默认值,如果这个ip是第一次来,字典中没有,就返回一个默认值0
            times = self.visit_times.get(ip_address,0)
            print('ip ',ip_address,'已经访问',times)
    
            #在当前的基础上+1.使用字典非常方便
            self.visit_times[ip_address] = times + 1
            if times < 5:
                return  None
            #当大于等于5次时被禁止
            return HttpResponse('您已经访问过'+str(times)+'次,访问被禁止')
    

    写完之后记得在settings.py 文件中的MIDDLEWARE中注册。

  5. 自己编写网站时,提交post请求时会被中间件’django.middleware.csrf.CsrfViewMiddleware’,拦截,在网页中提交post请求的标签中加入{% csrf_token %}即可。
    如果某个视图不需要django进行csrf保护,可以用装饰器关闭对此视图的检查:

    from django.views.decorators.csrf import csrf_exempt
    
    @csrf_exempt
     def my_view(request): ...
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值