Django drf节流
2019-02-28 本文已影响0人
Ginta
源码流程
- 和认证的流程一样,进入initial(request)
- 其中check_throttles(request)是节流的函数
- allow_request()就是节流函数(要复写)(get_throttles循环所有节流类)
- VisitThrottle自定义权限类
allow_request()返回值:
- True, 允许访问
- False, 访问太频繁
wait()返回值: - 返回一个整数,表示下次还有多久可以访问
使用
自定义类
class VisitThrottle(BaseThrottle):
def __init__(self):
self.history = []
def allow_request(self, request, view):
remote_addr = request.META.get('REMOTE_ADDR')
ctime = time.time()
if remote_addr not in VISIT_RECORD:
print("没有此IP")
VISIT_RECORD[remote_addr] = [ctime, ]
return True
history = VISIT_RECORD.get(remote_addr)
print(history)
while history and history[-1] < ctime-8:
history.pop()
self.history = history
if len(history) < 3:
history.insert(0, ctime)
return True
def wait(self):
ctime = time.time()
return 8-(ctime-self.history[-1])
在定义的类中复写allow_request方法,返回True或者False表示可以访问或者访问频率太高
引入
- 全局
# settings.py
'DEFAULT_THROTTLE_CLASSES': ['apps.api.utils.throttle.UserThrottle'],
- 局部
class AuthView(APIView):
"""
用于用户登录认证
"""
throttle_classes = [VisitThrottle,]
自定义类继承内置类
# throttle.py
from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
scope = "Vistor"
def get_cache_key(self, request, view):
return self.get_ident(request)
class UserThrottle(SimpleRateThrottle):
scope = "User"
def get_cache_key(self, request, view):
return self.user.username
scope从settings.py中寻找DEFAULT_THROTTLE_RATES字典的Key,就是访问频率限制,scope可以区分不同的函数的不同限制;get_cache_key(self, request, view)返回一个唯一标示用以区分不同的用户,对于匿名用户返回IP保存到缓存中限制访问,对于注册的用户取用户名(唯一)来区分就可以。
# settings.py
'DEFAULT_THROTTLE_RATES': {
'Vistor': '3/m',
'User': '10/m'
},