频率
1.内置频率类
1.1直接使用内置频率类
内置的频率限制(限制未登录用户)
# 全局使用 限制未登录用户1分钟访问5次
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'anon': '3/m',
}
}
##############views.py
from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication,BasicAuthentication
class TestView4(APIView):
authentication_classes=[]
permission_classes = []
def get(self,request,*args,**kwargs):
return Response('我是未登录用户')
# 局部使用
from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication,BasicAuthentication
from rest_framework.throttling import AnonRateThrottle
class TestView5(APIView):
authentication_classes=[]
permission_classes = []
throttle_classes = [AnonRateThrottle]
def get(self,request,*args,**kwargs):
return Response('我是未登录用户,TestView5')
内置频率限制之,限制登录用户的访问频次
# 需求:未登录用户1分钟访问5次,登录用户一分钟访问10次
全局:在setting中
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'user': '10/m',
'anon': '5/m',
}
局部配置:
在视图类中配一个就行
1.2调用内置频率类:需要自己写个类,然后继承SimpleRateThrottle
# 限制用户的访问次数:根据用户ip地址限制
# 访问者IP地址
-request.META.get('REMOTE_ADDR')
#####内置频率类的使用
# 1 写一个类,继承SimpleRateThrottle,重写get_cache_key,返回ip就以ip限制
# 2 在类中写一个类属性:scope = 'ip_m_3'
class MyThrotting(SimpleRateThrottle):
scope = 'ip_m_3'
def get_cache_key(self, request, view):
return self.get_ident(request) # 返回
# 3 在settings.py中写
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
# key值是频率类中scop字段对应的值,value是访问次数限制
'ip_m_3': '3/m',# 一分钟限制用户登录三次
}
}
### 局部使用和全局使用
-配置在视图类中
class IndexView(APIView):
throttle_classes = [MyThrotting, ]
-配置在settings.py中
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': ['app01.auth.MyThrotting',],
}
2 自定义频率类
2.1 编写频率类
# 自定义的逻辑
#(1)取出访问者ip
#(2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
#(3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
#(4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
#(5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
class MyThrottles():
VISIT_RECORD = {}
def __init__(self):
self.history=None
def allow_request(self,request, view):
#(1)取出访问者ip
# print(request.META)
ip=request.META.get('REMOTE_ADDR')
import time
ctime=time.time()
# (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问
if ip not in self.VISIT_RECORD:
self.VISIT_RECORD[ip]=[ctime,]
return True
self.history=self.VISIT_RECORD.get(ip)
# (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
while self.history and ctime-self.history[-1]>60:
self.history.pop()
# (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
# (5)当大于等于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])
2.2 全局使用
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES':['app01.utils.MyThrottles',],
}
2.3局部使用
#在视图类里使用
throttle_classes = [MyThrottles,]
3 其他
1) AnonRateThrottle
限制所有匿名未认证用户,使用IP区分用户。
使用DEFAULT_THROTTLE_RATES['anon']
来设置频次
2)UserRateThrottle
限制认证用户,使用User id 来区分。
使用DEFAULT_THROTTLE_RATES['user']
来设置频次
3)ScopedRateThrottle
限制用户对于每个视图的访问频次,使用ip或user id。
例如:
class ContactListView(APIView):
throttle_scope = 'contacts'
...
class ContactDetailView(APIView):
throttle_scope = 'contacts'
...
class UploadView(APIView):
throttle_scope = 'uploads'
...
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.ScopedRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'contacts': '1000/day',
'uploads': '20/day'
}
}
全局配置中设置访问频率
'DEFAULT_THROTTLE_RATES': {
'anon': '3/minute',
'user': '10/minute'
}
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
from rest_framework.throttling import UserRateThrottle
class StudentAPIView(RetrieveAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
throttle_classes = (UserRateThrottle,)