DRF

在 app 目录下创建 utils 目录,并在该目录下创建 throttle.py

throttle.py:

from rest_framework.throttling import BaseThrottle
import time


# 访问记录
VISIT_RECORD = {}


class MyThrottle(BaseThrottle):
    """
    每 10 秒访问 3 次
    """

    def __init__(self):
        self.history = None  # 用于记录访问记录

    def allow_request(self, request, view):
        # 获取用户的 IP 地址
        # 封装后的 request 中如果有的就不需要到 request._request 中找
        remote_addr = request.get_ident(request)
        ctime = time.time()  # 获取当前时间

        # 如果 IP 还没记录,即第一次访问
        if remote_addr not in VISIT_RECORD:
            # 记录第一次访问的 IP 地址和访问时间
            VISIT_RECORD[remote_addr] = [ctime, ]
            return True

        # 获取访问记录
        history = VISIT_RECORD.get(remote_addr)
        self.history = history

        # 把当前时间减 10 并和列表中最早的时间进行比较
        while history and history[-1] < ctime - 10:
            history.pop()  # 删除最早的一条记录

        # 如果还没有 3 条记录
        if len(history) < 3:
            # 将最新的访问时间插入到列表的第一个位置
            history.insert(0, ctime)
            print(history)
            return True

        return False

    # 设置剩余访问时间的提示
    def wait(self):
        ctime = time.time()
        return 10 - (ctime - self.history[-1])

history 列表的记录图示:

越早的访问记录放在列表的越后面的位置,方便操作

settings.py 中可以配置全局访问频率类:

REST_FRAMEWORK = {
    # 全局使用的访问频率类
    "DEFAULT_THROTTLE_CLASSES": ["drf.utils.throttle.MyThrottle"],
}

 views.py:

from django.http import JsonResponse
from rest_framework.views import APIView
from drf.utils.throttle import MyThrottle


ORDER_DICT = {
    1: {
        "commodity": "Phone",
        "price": 3600,
        "date": "2021-01-03",
    },
    2: {
        "commodity": "Computer",
        "price": 6700,
        "date": "2021-01-05",
    },
}


class OrderView(APIView):
    """
    查看订单
    """

    # 设置访问频率类
    throttle_classes = [MyThrottle, ]

    def get(self, request, *args, **kwargs):
        response = {"code": 1000, "msg": None, "data": None}
        try:
            response["data"] = ORDER_DICT
        except Exception as e:
            pass
        return JsonResponse(response)

10 秒内前 3 次可正常访问,访问第 4 次:

原文地址:https://www.cnblogs.com/sch01ar/p/14289143.html