DRF频率组件

频率组件源码:

 APIView的initial方法:(执行APIView的as_view方法,执行APIView的dispatch方法,执行APIView的initial方法)

 APIView的check_throttles方法

跟认证组件和权限组件一样。throttle是配置的每个频率控制类的实例化对象,配置文件中的"DEFAULT_THROTTLE_CLASSES"

并且每个频率控制类都有allow_request和wait方法

把所有频率组件走一遍,然后把等待时间最长的作为异常抛出

 APIView的throttled方法,抛出异常

自己实现的频率控制类:

在项目目录下创建utils目录,创建throttle.py

from rest_framework.throttling import BaseThrottle
import time

VISIT_RECORD = {}  # 访问列表


class MyThrottle(BaseThrottle):
    def __init__(self):
        self.history = None

    def allow_request(self, request, view):
        # 实现限流的逻辑
        # 以IP地址限流
        # IP地址的访问列表 {IP:[time1, time2, time3]}
        # 1. 获取请求的IP地址
        ip = request.META.get("REMOTE_ADDR")
        # 2. 判断IP地址是否在访问列表
        #     --1  不在,需要给访问列表添加key value
        now = time.time()
        if ip not in VISIT_RECORD:
            VISIT_RECORD[ip] = [now, ]
            return True
        #     --2  在,需要把这个IP的访问记录 把当前时间加入到列表头部(也可以是尾部)
        history = VISIT_RECORD[ip]
        history.insert(0, now)
        # 3. 确保列表里最新访问时间以及最老的访问时间差 是1分钟(假如限制时间是1分钟)
        while history and history[0] - history[-1] > 60:  # 执行完该循环,列表里的时间都是一分钟之内的了
            history.pop()
        self.history = history
        # 4. 得到列表长度,判断是否是允许的次数(假设允许1分钟最多3次)
        if len(history) > 3:
            return False
        else:
            return True

    def wait(self):
        # 返回需要等待的时间
        wait_time = 60 - (self.history[0] - self.history[-1])
        return wait_time

在视图中使用:

from utils.throttle import MyThrottle


class DemoView(APIView):
    throttle_classes = [MyThrottle, ]

    def get(self, request):
        return Response("测试限流类")

框架自带的限流类用法(跟我们自己实现的同样功能,每分钟限制3次):

 配置settings:

原文地址:https://www.cnblogs.com/staff/p/12621148.html