restframework的频率

 

 

控制用户的访问频率,比如一分钟内某一个用户只允许访问三次,我们就需要用到频率组件

 

自定义用户访问频率组件的逻辑:

1.定义一个用户访问的字典,用户访问时取出他ip
2.判断ip在不在字典里,不在就添加进去并返回True,表示第一次访问
3.循环判断当前ip的列表,列表里有值的话就用当前的时间减去列表的最后一个时间,大于60s就把这个数据pop掉,这样列表中只有60s之内的访问时间了

4.判断列表是否小于3,小于3表示一分钟内访问的不足三次,把当前时间插入到列表的第一个位置,返回True并顺利通过
5.当大于3说明一分钟内访问超过三次,返回False验证失败

 

 

 

代码实现:

class MyThrottles():
    VISIT_RECORD = {}
    def __init__(self):
        self.history=None
    def allow_request(self,request, view):
        # 取出访问者ip
        # print(request.META)
        ip=request.META.get('REMOTE_ADDR')
        import time
        ctime=time.time()
        # 判断当前ip在不在字典里,不在就添加进去并返回True,表示第一次访问
        if ip not in self.VISIT_RECORD:
            self.VISIT_RECORD[ip]=[ctime,]
            return True
        self.history=self.VISIT_RECORD.get(ip)
        # 循环判断当前ip的列表,有值的话就用当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
        while self.history and ctime-self.history[-1]>60:
            self.history.pop()
        # 判断列表是否小于3,小于则说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
        # 当大于等于3,说明一分钟内访问超过三次,返回False验证失败
        if len(self.history)<3:
            self.history.insert(0,ctime)
            return True
        else:
            return False
    def wait(self):
        import time
        ctime=time.time()
        return 60-(ctime-self.history[-1])

 

 

限制频率的局部使用

 

 

# 写一个类,继承自SimpleRateThrottle,(根据ip限制)

from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
    scope = 'restrict'
    def get_cache_key(self, request, view):
        return self.get_ident(request)

# 在setting里配置:(一分钟访问三次) REST_FRAMEWORK = { 'DEFAULT_THROTTLE_RATES':{ 'restrict':'3/m' } }

# 在视图类里使用 throttle_classes = [MyThrottles,]

 

 

 

用户限制次数的中文提示:

class Course(APIView):
    throttle_classes = [MyThrottles,]

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

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


    def throttled(self, request, wait):
        from rest_framework.exceptions import Throttled
        class MyThrottled(Throttled):
            default_detail = '稍后重试'
            extra_detail_singular = '还有 {wait} second.'
            extra_detail_plural = '出了 {wait} seconds.'
        raise MyThrottled(wait)

 

全局使用:

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES':['app01.utils.VisitThrottle',],
    'DEFAULT_THROTTLE_RATES':{
        'restrict':'3/m'
    }
}

 

posted @ 2020-08-11 23:20  不忘初心❤  阅读(149)  评论(0编辑  收藏  举报