rest_framework之访问频率控制

一  自定义频率控制类

class MyThrottle():
    visitor_dic = {}

    def __init__(self):
        self.history = None

    def allow_request(self, request, view):
        '''
            {'ip1':[时间1 ,时间2],
            'ip2':[时间1, ],
            }
           #(1)取出访问者ip
            # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
            # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
            # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
            # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
        '''

        # Meta:请求所有的东西的字典
        # 拿出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
        while history and ctime - history[-1] > 60:
            history.pop()

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

        return False

    def wait(self):
        # 剩余时间
        ctime = time.time()
        return 60 - (ctime - self.history[-1])

二  内置频率控制

在app中新建一个文件,来放相关组件:

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

在settings中配置访问:

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES':{
        'hhh':'3/m'
    }
}

在视图函数中:(局部配置)

throttle_classes = [MyThrottles,]

错误信息提示转换为中文:

class Course(APIView):
    authentication_classes = [TokenAuth, ]
    permission_classes = [UserPermission, ]
    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)

其他

内置频率限制类:

BaseThrottle是所有类的基类:方法:def get_ident(self, request)获取标识,其实就是获取ip,自定义的需要继承它

AnonRateThrottle:未登录用户ip限制,需要配合auth模块用

SimpleRateThrottle:重写此方法,可以实现频率现在,不需要咱们手写上面自定义的逻辑

UserRateThrottle:登录用户频率限制,这个得配合auth模块来用

ScopedRateThrottle:应用在局部视图上的(忽略)

内置频率全局配置:

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

 

posted @ 2018-12-14 16:56  zhaijihai  阅读(272)  评论(0编辑  收藏  举报