也存在全局使用和部分使用:
REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ['app01.MyAuth.MyThrottle'], # 下面是设置访问几次的权限 'DEFAULT_THROTTLE_RATES': { # django内置会把它切分,2为访问的次数,m为时间 'aaa': '2/m' } }
1,路由配置
在自定义文件里:
自定义组件可以继承下面:
BaseThrottle是所有类的基类:方法:def get_ident(self, request)获取标识,其实就是获取ip,自定义的需要继承它
AnonRateThrottle:未登录用户ip限制,需要配合auth模块用
SimpleRateThrottle:重写此方法,可以实现频率现在,不需要咱们手写上面自定义的逻辑
UserRateThrottle:登录用户频率限制,这个得配合auth模块来用
ScopedRateThrottle:应用在局部视图上的(忽略)
2,视图层
class Test(APIView): throttle_classes = [MyThrottle, ] # parser_classes = [FormParser,] def get(self, request): # print(request._request) # print(type(request._request)) return HttpResponse('ok') def post(self, request): print(request.data) return HttpResponse('post') # 访问次数超过限制时报错信息的修改 def throttled(self, request, wait): class MyThrottled(exceptions.Throttled): # 下面字符串的拼接 default_detail = 'xx' extra_detail_singular = '还剩 {wait} 秒.' extra_detail_plural = '还剩 {wait} 秒' raise MyThrottled(wait)
3,自定义组件的文件中,
class MyThrottle(SimpleRateThrottle): scope = 'aaa' def get_cache_key(self, request, view): # 返回ip地址 # ip = request.META.get('REMOTE_ADDR') # return ip return self.get_ident(request)
二,不用django内置的接口,自定义频率限制
先定义一个Ip对应一个存放时间的列表,访问一次添加一次
1,获取访问的Ip
2,查询Ip是否存在列表中,如果存在则往下进行,如果不存在则返回true
3,循环列表中的每个时间(从-1开始),与当前时间对比,如果超出则删除,直到括号里面没有差距为一分钟的时间
4,判断列表中的个数,如果超出三个,则返回false
5,满足条件直接返回true
class MyThrottle(BaseThrottle): visitor_dic = {} def __init__(self): self.history = None def allow_request(self, request, view): # 拿出请求的Ip ip = request.META.get('REMOTE_ADDR') print(ip) # 获取当前时间 ctime = time.time() # 判断ip是否存在字典中 if ip not in self.visitor_dic: self.visitor_dic[ip] = [ctime, ] print(self.visitor_dic) 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) print(self.visitor_dic) return True print(self.visitor_dic) return False # 当访问的次数超过了你设置的次数时,要设置提示时间 def wait(self): # 剩余时间(访问超过了次数才会执行) ctime = time.time() return 60-(ctime - self.history[-1])