Django - DRF - SimpleRateThrottle 频率组件

目录

一、实现自定义访问频率控制逻辑 - BaseThrottle

1-1 访问频率实现思路(一个ip一分钟只能访问3次)

1-2 访问频率逻辑实现

1-3 源码分析

二、DRF 内置频率类 - SimpleRateThrottle

2-1 频率控制实现

 2-2 源码分析

三、频率类的使用配置

3-1 局部配置

3-2 全局配置 及 局部禁用

四、频率错误信息的中文显示 - 即 throttled 方法重写

4-1 源码分析

4-2 重写throttled方法


一、实现自定义访问频率控制逻辑 - BaseThrottle

1-1 访问频率实现思路(一个ip一分钟只能访问3次)

  1. 取出访问者ip - request.MATE.get('REMOTE_ADDR ')
  2. 第一次访问:判断当前ip不在访问字典里添加进去,并且直接返回True,表示第一次访问  - {‘ip1’:[time1,]}
  3. 非第一次访问:判断当前ip在访问字典里,继续往下走 - {‘ip1’:[time1,time2]}
  4. 循环当前ip的列表,若非空,则取出符合 当前时间 - 列表末尾时间 > 60s 的对象时间,进行pop删除操作。- 保证列表中只存在未超过间隔60s的访问时间
  5. 判断操作
    1. 列表长度<3 - 一分钟内访问不超过三次,将当前时间插入列表第一位返回True,表示验证成功
    2. 列表长度>3 - 一分钟内访问次数唱过三次,返回False,表示验证失败

1-2 访问频率逻辑实现

总结:

  • 频率类
    • 必须重写allow_request(self, request, view) 方法
    • 若频率验证通过 : 返回True
    • 若频率验证不通过:返回False
    • 必须重写 wait 方法用于频率验证不通过之后等待
  • 视图类
    • 局部使用 - throttle_classes = [drfAuth.MyThrottle, ]
'''
drfAuth.py - 基于DRF的自定义频率实现
'''

import time


class MyThrottle():
    # 用于存放ip列表
    visitor_dic = {}

    def __init__(self):
        self.history = None

    def allow_request(self, request, view):
        # MATA:请求header内数据
        # REMOTE_ADDR:获取ip地址
        ip = request.META.get('REMOTE_ADDR')

        ctime = time.time()
        # 不在字典中 - 第一次访问
        if ip not in self.visitor_dic:
            self.visitor_dic[ip] = [ctime, ]
            return True

        # 根据当前访问者ip,取出访问的时间列表
        history = self.visitor_dic[ip]
        self.history = history
        # history[-1]:访问时间列表最后一个
        while history and ctime - history[-1] > 60:
            history.pop()

        if len(history) < 3:
            # 把当前时间放到第0个位置上
            history.insert(0, ctime)
            return True

        return False

    # 若前方频率范围Flase则60s后才能进行操作
    def wait(self):
        # 剩余时间
        ctime = time.time()
        return 60 - (ctime - self.history[-1])

'''
view视图函数
'''
class FrequencyTest(APIView):
    throttle_classes = [drfAuth.MyThrottle, ]

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

1-3 源码分析

'''
check_throttles
    APIView - dispatch - initial - check_throttles
'''
def check_throttles(self, request):
"""
Check if request should be throttled.
Raises an appropriate exception if the request is throttled.
检查是否应控制请求。如果控制了请求,则引发适当的异常。
"""
for throttle in self.get_throttles():
    # 判断指定对象内是否存在allow_request,必须传入request,和基于APIView的试图类
    # 所以,在自己的频率控制中,返回必须为True or False
	if not throttle.allow_request(request, self):
        # 若频率控制返回False 则执行类内的wait()方法抛出异常
		self.throttled(request, throttle.wait())

'''
get_throttles
'''
def get_throttles(self):
	"""
	Instantiates and returns the list of throttles that this view uses.
    实例化并返回视图使用的节流阀列表。
	"""
	return [throttle() for throttle in self.throttle_classes]		

'''
throttled
'''
def throttled
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值