django rest framework系列08-基于IP和用户实现继承内置访问频率限制实现自定义访问频率控制

SimpleRateThrottle这个类写的其实挺完整了,我们继承他适当配置下就可以了
def allow_request(self, request, view):
    """
    Implement the check to see if the request should be throttled.

    On success calls `throttle_success`.
    On failure calls `throttle_failure`.
    """
    if self.rate is None:
        return True

    self.key = self.get_cache_key(request, view)# 这里跟进去看了没写,需要我们自定义一个key
    if self.key is None:
        return True

    self.history = self.cache.get(self.key, []) #这里跟进去看了cache。get获取的是django的缓存,也就是,取django缓存中找我们需要的kye。
    self.now = self.timer()  #获取当前时间戳,跟进去看过

    # Drop any requests from the history which have now passed the
    # throttle duration
    while self.history and self.history[-1] <= self.now - self.duration:
        self.history.pop()
    if len(self.history) >= self.num_requests:  #如果我们保持的列表成员数大于设置好的频次。这个num_requests上一篇讲过失去配置文件找我们是自定义了
        return self.throttle_failure()  #返回False
    return self.throttle_success() #insert后返回True

def throttle_success(self):
    """
    Inserts the current request's timestamp along with the key
    into the cache.
    """
    self.history.insert(0, self.now)
    self.cache.set(self.key, self.history, self.duration)
    return True

def throttle_failure(self):
    """
    Called when a request to the API has failed due to throttling.
    """
    return False

 

 通过分析上面代码,发现我们需要一个kye,保存到系统缓存。如果全部用内置的方法,那么self.duration和self.num_requests我们用内置的方法。

看下获取这个这两个参数的位置:

def __init__(self):
    if not getattr(self, 'rate', None):
        self.rate = self.get_rate()
    self.num_requests, self.duration = self.parse_rate(self.rate)#传入上面的参数

 self.get_rate()方法内部

def get_rate(self):
    """
    Determine the string representation of the allowed request rate.
    """
    if not getattr(self, 'scope', None):
        msg = ("You must set either `.scope` or `.rate` for '%s' throttle" %
               self.__class__.__name__)
        raise ImproperlyConfigured(msg)

    try:
        return self.THROTTLE_RATES[self.scope]  #正常情况下返回要给self.THROTTLE_RATES的[self.scope].这个scope是None,没有写,THROTTLE_RATES是THROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATES
#也就是去配置文件DEFAULT_THROTTLE_RATES内获取的,这里我们可以通过,列表下标scope,也可以用字典key作为scope反正是能取到那个值就行。
    except KeyError:
        msg = "No default throttle rate set for '%s' scope" % self.scope
        raise ImproperlyConfigured(msg)

 需要配置的值,之前我们是看过的,再说一遍self.parse_rate(self.rate)内部:

def parse_rate(self, rate):
    """
    Given the request rate string, return a two tuple of:
    <allowed number of requests>, <period of time in seconds>
    """
    if rate is None:
        return (None, None)
    num, period = rate.split('/')  #参数是以斜杠分割,前面是访问次数,后面是s/m或者H/D
    num_requests = int(num)
    duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]
    return (num_requests, duration)

 那么根据以上分析:配置文件就这样写

REST_FRAMEWORK ={
    'DEFAULT_AUTHENTICATION_CLASSES':['API.utils.auth.Authtication',],
    'DEFAULT_THROTTLE_CLASSES':['API.utils.throttle.myThrottle',], #这里等会就不能用这个了,后面再改。
    'DEFAULT_THROTTLE_RATES':{'Access':'10/m'}
}

 现在就差一个KEY了。赶快再去自定义一个类。写个key的获取方法就ok了

class myThrottle3(SimpleRateThrottle):
    scope = 'Access' #配置文件中获取的key

    def get_cache_key(self, request, view):
        """
        父类中没有写的需要我们写的。这里可以用IP,或者用户名作为key来保存记录到django缓存。
        :param request:
        :param view:
        :return:
        SimpleRateThrottle类继承于BaseThrottle,他里面有个方法,get_ident。返回就是我们需要的IP
        """
        key = self.get_ident(request)
        print(key)
        return key

配置文件中使用我们新定义的类。

REST_FRAMEWORK ={
    'DEFAULT_AUTHENTICATION_CLASSES':['API.utils.auth.Authtication',],
    'DEFAULT_THROTTLE_CLASSES':['API.utils.throttle.myThrottle3',],
    'DEFAULT_THROTTLE_RATES':{'Access':'3/m'}
}

 这样全局使用这个类,如果局部不使用,跟之前一样视图内定义throttle_classes赋值一个空列表,或者自定义的其他类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值