详解Django-restframework 之频率源码分析
程序员文章站
2022-04-28 17:29:03
一 前言
经过权限判断之后就是进行频率的判断了,而频率的判断和权限又不一样,认证、权限和频率的执行流程都差不多,使用配置里面的相关类来进行判断。而不和认证和权限一样,频率...
一 前言
经过权限判断之后就是进行频率的判断了,而频率的判断和权限又不一样,认证、权限和频率的执行流程都差不多,使用配置里面的相关类来进行判断。而不和认证和权限一样,频率的配置没有,查看 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 = []
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: python制作mysql数据迁移脚本
下一篇: YII框架页面缓存操作示例