一 前言
经过权限判断之后就是进行频率的判断了, 而频率的判断和权限又不一样, 认证, 权限和频率的执行流程都差不多, 使用配置里面的相关类来进行判断. 而不和认证和权限一样, 频率的配置没有, 查看 APIView 的类属性如下:
二 频率组件执行流程
虽然 restframework 原生灭有配置频率, 但是提供了几个进行频率判断的类, 如下:
其中 SimpleRateThrottle 类是根据访问者 ip 来进行频率限制的一个类, 来看看这个类的执行流程.
1. init 方法
2. get_rate
3. 执行 allow_request 方法
4. get_cache_key
5. 时间差判断
6. throttle_success
认证失败的话执行 throttle_failure, 其实就是返回 False.
7. wait
三 自定义频率组件
1. 自定义频率类
频率类需要继承自带的频率类
- # from rest_framework.throttling import BaseThrottle
- class BookThrottle(BaseThrottle):
- VISIT_RECORD = {}
- def __init__(self):
- self.history = None
- def allow_request(self, request, view):
- print(request.META)
- REMOTE_ADDR = request.META.get('REMOTE_ADDR')
- import time
- ctime = time.time()
- if REMOTE_ADDR not in self.VISIT_RECORD:
- self.VISIT_RECORD[REMOTE_ADDR] = [ctime,]
- return True
- self.history = self.VISIT_RECORD.get(REMOTE_ADDR)
- while self.history and ctime - self.history[-1]> 60:
- self.history.pop()
- 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])
- # 频率类代码注释
- # 访问频率的逻辑
- # # {'ip 地址':[16:13:39,16:13:19,],'ip 地址 2':[时间 1, 时间 2],}
- # # (1) 取出访问者 ip
- # # (2) 判断当前 ip 不在访问字典里, 添加进去, 并且直接返回 True, 表示第一次访问, 在字典里, 继续往下走
- # # (3) 循环判断当前 ip 的列表, 有值, 并且当前时间减去列表的最后一个时间大于 60s, 把这种数据 pop 掉, 这样列表中只有 60s 以内的访问时间,
- # # (4) 判断, 当列表小于 3, 说明一分钟以内访问不足三次, 把当前时间插入到列表第一个位置, 返回 True, 顺利通过
- # # (5) 当大于等于 3, 说明一分钟内访问超过三次, 返回 False 验证失败
- # #(1) 取出访问者 ip
- # # print(request.META)
- # # REMOTE_ADDR 就是访问者的 ip:127.0.0.1
- # 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,]
- # # {'127.0.0.1':[时间 1, 时间 1,]}
- # return True
- # # self.history=[时间 1, 时间 1,]
- # 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
2. 使用
使用很简单, 在需要进行频率控制的视图类中定义一个属性 throttle_classes, 如下:
- class Book(APIView):
- authentication_classes = [authticate_classes.BookAuth]
- permission_classes = [permiss_classes.LoginPermission]
- throttle_classes = [thrott_classes.BookThrottle]
- # authentication_classes = []
- def dispatch(self, request, *args, **kwargs):
- return super().dispatch(request, *args, **kwargs)
- def get(self, request, id):
- print(request.user, '444')
- response = {'status': 100, 'msg': None}
- book_obj = models.Book.objects.filter(pk=id).first()
- if book_obj:
- book_ser = myser.BookSer(book_obj, many=False)
- response['book'] = book_ser.data
- else:
- response['msg'] = '图书没有对象'
- response['status'] = 101
- return Response(response)
四 配置自定义频率类
1. 局部配置
其实上面的就是局部配置,
- class Book(APIView):
- authentication_classes = [authticate_classes.BookAuth]
- permission_classes = [permiss_classes.LoginPermission]
- throttle_classes = [thrott_classes.BookThrottle]
2. 全局使用
全局配置如下:
- REST_FRAMEWORK={
- 'DEFAULT_THROTTLE_CLASSES': ['app01.thrott_classes.BookThrottle']
- }
3. 局部禁用
局部禁用需要在视图类中定义一个空的 throttle_classes 属性
throttle_classes = []
来源: http://www.bubuko.com/infodetail-2968856.html