Django框架(二十九:rest_framework 节流)

自定义节流的方法 ,限制60s内只能访问3次

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
import time
class ThrottleAuth(BaseThrottle):
    # 声明一个字典,用于保存不同用户的访问时间。
    visit_dict = {}
    def __init__(self):
        # visit_historys该变量就是用来记录用户每次的访问时间。
        self.visit_historys = []
    def allow_request(self, request, view):
        """
        认证用户是否能够向这个API接口发起请求。返回值是True,就可以访问;反之,就不能访问;
        :param request:
        :param view:
        :return:
        """
        # 1. 先从请求中获取对方的IP地址;
        IP = request.META.get('REMOTE_ADDR')
        # 2. 获取当前用户向API接口发送请求的时间
        current_time = time.time()
        if IP not in self.visit_dict:
            # 3. 如果获取的当前IP,在self.visit_dict字典中不存在,说明这个IP地址是第一次访问。
            self.visit_dict[IP] = [current_time]
            # 此时返回True,访问次数不够,可以继续访问。
            return True
        # 4. 如果这一次的IP在记录中已经存在了,说明不是第一次访问,和第一次访问的时间进行对比。
        # 获取IP对应的时间列表
        history = self.visit_dict.get(IP)
        self.visit_historys = history
        while history and history[-1] < current_time - 60:
            # 当前时间-60s 大于 第一次访问的时间,说明这一次的访问和上一次的访问时间不在1分钟之内。
            # 将列表中的[-1]对应的数据删除
            history.pop()
        # 5. 经过上述循环之后,列表中剩余的都是1分钟之内的时间了。
        if len(history) < 5:
            # 可以访问,1分钟之内访问没有超过5次。
            history.insert(0, current_time)
            return True
        # 6. 当前访问总次数 >= 5次,不能再访问这个接口了。
        return False
#全局
REST_FRAMEWORK = {
    #节流
    "DEFAULT_THROTTLE_CLASSES":['API.utils.throttle.VisitThrottle'],
}

源码分析
dispatch()->initial()
Django框架(二十九:rest_framework 节流)_第1张图片

check_throttles()
Django框架(二十九:rest_framework 节流)_第2张图片

allow_request():
返回值True/False

内置节流类
SimpleRateThrottle
get_ident也是获取ip

class IPThrottle(SimpleRateThrottle):
    """
    对于匿名用户的控制
    使用throttling.py中的内置的访问控制类来实现API的访问控制。
    """
    scope = 'IP'
    def get_cache_key(self, request, view):
        return request.META.get('REMOTE_ADDR')


class UserThrottle(SimpleRateThrottle):
    """
    对于已登录用户的控制
    使用throttling.py中的内置的访问控制类来实现API的访问控制。
    """
    scope = 'USER'
    def get_cache_key(self, request, view):
        return request.user.username

settings.py

# 配置自定义的访问控制类
    'DEFAULT_THROTTLE_CLASSES': ['utils.base_authenticate.IPThrottle'],
# 使用Throttle内置的访问控制类
    'DEFAULT_THROTTLE_RATES': {
        'IP': '3/m', # 'IP'就是源码中的scope, '3/m'就是源码中的rate。
        'USER': '10/m', # 'USER'就是源码中的scope, '10/m'就是源码中的rate。
    },

你可能感兴趣的:(Django,前后端分离,rest_framework)