django中间件学习

中间件简述

中间件是一个轻量级的,底层的插件,可以介入Django的请求和相应过程(面向切面编程AOP)
中间件本质是一个python类。
面向切面编程AOP:主要实现目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合的隔离效果。

django的请求流程

django的请求流程:Browser-->url分发器-->views-->models-->views-->temlates-->browser.

中间件切点

django内置了4个切点和1个异常捕获点。

4个切点位置
* process_request:切点位于Browser和url分发器之间。
* process_view: 切点位于url分发器和views之间。
* process_template_response: 切点位于views和templates之间任意位置。
* process_response: 切点位于templates和Browser之间。

切入函数内容:
__init__:没有参数,服务器响应第一个请求的时候自动调用,用户确定是否启动该中间件。
* process_request(self, request):在执行视图前被调用,每个请求上都会调用,不主动进行返回或返回HttpResponse对象。
* process_view(self, request,view_func,view_args,view_kwargs): 调用视图之前执行,每个请求都会调用,不主动进行返回或返回HttpResponse对象。
* process_template_response(self, request,response): 在视图刚好执行完之后执行,每个请求都会调用,不主动进行返回或返回HttpResponse对象。
* process_response(self, request,response): 所有响应返回浏览器之前调用,每个请求都会调用,不主动进行返回或返回HttpResponse对象。
process_exception(self, request,exception): 当视图抛出异常时调用,不主动进行返回或返回HttpResponse对象。

自定义中间件流程

1.在工程目录下创建middleware目录。
2.目录中创建一个python文件。
3.在Python文件中倒入中间的基类。from django.utils. deprecation import MiddlewareMixin
4.在类中根据功能需求,创建切入需求类,重写切入点方法。
5.启用中间件,在settings中进行配置,MIDDLEWARE中添加创建的middleware文件名(全路径)+类名。

AOP中间件常见用途

  • 实现统计功能:
    统计IP,统计浏览器
  • 实现权重控制:
    黑名单,白名单
  • 实现反爬:
    反爬虫,频率控制
  • 界面友好化,应用交互友好化:
    应用异常不显示500报错,显示指定提示页面。

代码案列

1.实现频率控制和反爬策略,每分钟最多访问10次,超过10次限制访问,超过30次加入黑名单并限制24小时访问。

import time
from django.core.cache import cache
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin


class LimitMiddle(MiddlewareMixin):
    def process_request(self, request):
        print(request.META.get("REMOTE_ADDR"))
        ip = request.META.get("REMOTE_ADDR")
        black_list = cache.get('black', [])
        if ip in blank_list:
            return HttpResponse('黑名单用户,禁止访问。')

        requests = cache.get(ip, [])
        while requests and time.time() - requests[-1] > 60:
            requests.pop()

        requests.insert(0, time.time())
        cache.set(ip, requests, timeout=60)

        if len(requests) > 30:
            blank_list.append(ip)
            cache.set('blank', blank_list, timeout=60*60*24)
            return HttpResponse("访问次数过多,加入黑名单")

        if len(requests) > 10:
            return HttpResponse("请求次数过于频繁!")

2.捕获异常,让用户看不到500系列报错。

from django.utils.deprecation import MiddlewareMixin


class LimitMiddle(MiddlewareMixin):
    def process_request(self, request):
        pass
    
    def process_exception(self, request, exception):
        print(request, exception)
        return redirect(reverse('xxxx'))  # 重定向至指定页面

中间件的执行顺序

  • 调用顺序:中间件注册的时候是一个列表。如果在切点处没有遇到返回,中间件会按照注册顺序依次执行。如果遇到了返回,则后续中间件不再执行。
  • 切点顺序:process_request process_view process_template_reponse process_response process_exception
posted @ 2021-02-28 12:11  dsprain  阅读(120)  评论(0)    收藏  举报