django-rest-framework限流

django-rest-framework限流

在项目根目录下新建utils的文件

  • 新建throttling.py
from django_redis import get_redis_connection
from rest_framework.throttling import BaseThrottle
from django.conf import settings
import time


class MyThrottle(BaseThrottle):

    def __init__(self):
        # 定义实例化属性
        self.remote_addr = None
        self.throttle_times = settings.DEFAULT_THROTTLE_TIMES
        self.throttle_seconds = settings.DEFAULT_THROTTLE_SECONDS

    def allow_request(self, request, view):
        '''定义限流的处理逻辑'''
        # 获取用户的id
        # remote_addr = request.META.get('REMOTE_ADDR')
        remote_addr = self.get_ident(request)
        coon = get_redis_connection('default')
        self.remote_addr = remote_addr
        # 获取当前时间
        current_time = int(time.time())
        # 从左侧插入redis列表
        coon.lpush(remote_addr, current_time)
        # 保存最新5条信息
        coon.ltrim(remote_addr, 0, self.throttle_times - 1)
        # 获取总的5条记录
        times_byte_list = coon.lrange(remote_addr, 0, self.throttle_times - 1)
        # 将其中的byte转换成int
        times_list = [int(_) for _ in times_byte_list]
        # 判断是否符合条件
        if coon.llen(remote_addr) < self.throttle_times:
            return True
        return times_list[0] - times_list[-1] > self.throttle_seconds

    def wait(self):
        '''返回等待时长'''
        coon = get_redis_connection('default')
        first_time = coon.lindex(self.remote_addr, self.throttle_times - 1)
        current_time = int(time.time())
        return self.throttle_seconds - (current_time - int(first_time))

  • 自定义的截流类必须继承BaseThrottle, 且实现allow_request的成员方法
  • 返回为False表示不通过验证
  • wait方法返回一个int值,这个值会被返回到错误的信息中
  • 使用redis来操作访问记录
    • 采用列表的方式来存储
    • 采用用户的id地址来做键名
    • 定义配置来限制次数和时间段
    • 次数会被作为redis列表储存的长度
原文地址:https://www.cnblogs.com/ivy-blogs/p/11651155.html