首页 > 编程语言 >drf三大认证之频率类源码解析

drf三大认证之频率类源码解析

时间:2022-10-11 15:46:28浏览次数:64  
标签:None return get self rate 源码 scope 三大 drf

主要从SimpleRateThrottle的allow_request方法开始分析

第一步
1.查看SimpleRateThrottle的allow_request
  if self.rate is None:
            return True   # 表示没有超过频率限制 可以访问
第二步
2.查看rate
    def __init__(self):
        if not getattr(self, 'rate', None):   # 用了反射来获取rate 如果有则返回 没有返回None
            self.rate = self.get_rate()     # 由步骤4的推导得出 get_rate() 返回了'5/m'
        self.num_requests, self.duration = self.parse_rate(self.rate)    # 这里的(self.rate)就是5/m
        # 解压赋值以后的num_requests是5,duration是60
        
自己写的频率类里面没有这个rate 所以返回None,那么继续走下面的代码
第三步
3.查看 self.rate = self.get_rate()这里的get_rate
   还是在SimpleRateThrottle里面
       if not getattr(self, 'scope', None): 
            # 反射了一个scope 这个就是我们自己写的定义在类里的属性
            msg = ("You must set either `.scope` or `.rate` for '%s' throttle" %
                   self.__class__.__name__)
            raise ImproperlyConfigured(msg)

        try:
            return self.THROTTLE_RATES[self.scope]
        except KeyError:
            msg = "No default throttle rate set for '%s' scope" % self.scope
            raise ImproperlyConfigured(msg)
# 如果不写scope的话就会抛异常
有的话就执行 return self.THROTTLE_RATES[self.scope]

第四步
4.查看 THROTTLE_RATES[self.scope]
  THROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATES
  这个是按照scope键去我们配置的文件字典取值里取V值
    'throttling': '5/m'       throttling就是我们自定义的scope的名字
第五步
5.查看parse_rate
    def parse_rate(self, rate):
        if rate is None:   # 如果rate没有值则返回none
            return (None, None)
        num, period = rate.split('/')  # 有的话按斜杠切割一下 变成这种形式['5','m']
        num_requests = int(num)   # 把'5' 变成数字  
        duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]  # 此时的period[0]就是m
        return (num_requests, duration)     返回的就是 5,60
第六步
6.回到SimpleRateThrottle的allow_request的第二段代码
 第一段就是我们第一步查看的 以上就是它的rate里面值的查找过程
 现在的rate是有值的 那么会继续走下面的代码
 self.key = self.get_cache_key(request, view)  # 此时的self.get_cache_key就是我们继承以后重写的方法
        if self.key is None:    # key是我们以重写的以什么作为频率限制的返回值 自己是返回的IP
            return True   
第七步
7.有值的话代码继续往下走 
     self.history = self.cache.get(self.key, [])   # self.history访问者的时间列表 从缓存中获取
      # 如果有时间的话就是 ip[时间1,时间2] ,没有的话就是空列表ip[]
        self.now = self.timer()
        # 获取了当前时间
第八步
        
8.判断访问的频率
        while self.history and self.history[-1] <= self.now - self.duration:  
         # 循环访问者的时间列表,如果时间列表的最后一位小于或者等于当前时间减去60
            self.history.pop()   #就将它移除掉
        if len(self.history) >= self.num_requests: # 判断时间类表的长度是否大于或者等于之前列表配置的次数
            return self.throttle_failure()      #  throttle_failure()返回值是false 大于就限制了访问
        return self.throttle_success()  
第九步

9. 第八步如果访问次数没有超出配置的次数 那么返回下面代码的内容
   def throttle_success(self):
        self.history.insert(0, self.now)  # 将当前时间插入到访问时间列表的第一位
        self.cache.set(self.key, self.history, self.duration)  
         #将访问者的ip,时间列表,访问频率的时间 存放在缓存中 方便下次取数据
        return True
总结
 '''总结 : 以后写频率类的时候继承SimpleRateThrottle
    重写 get_cache_key方法 一定要写一个类属性 scope  配置文件一定要写
 '''

标签:None,return,get,self,rate,源码,scope,三大,drf
From: https://www.cnblogs.com/Hsummer/p/16779435.html

相关文章