详解Django-restframework 之频率源码分析


Posted in Python onFebruary 27, 2019

一 前言

经过权限判断之后就是进行频率的判断了,而频率的判断和权限又不一样,认证、权限和频率的执行流程都差不多,使用配置里面的相关类来进行判断。而不和认证和权限一样,频率的配置没有,查看 APIView 的类属性如下:

详解Django-restframework 之频率源码分析

详解Django-restframework 之频率源码分析

二 频率组件执行流程

虽然 restframework 原生灭有配置频率,但是提供了几个进行频率判断的类,如下:

详解Django-restframework 之频率源码分析

其中 SimpleRateThrottle 类是根据访问者 ip 来进行频率限制的一个类,来看看这个类的执行流程。

1. init方法

详解Django-restframework 之频率源码分析

2. get_rate

详解Django-restframework 之频率源码分析

3. 执行 allow_request方法

详解Django-restframework 之频率源码分析

4. get_cache_key

详解Django-restframework 之频率源码分析

5. 时间差判断

详解Django-restframework 之频率源码分析

6. throttle_success

详解Django-restframework 之频率源码分析

认证失败的话执行 throttle_failure ,其实就是返回 False

7. wait

详解Django-restframework 之频率源码分析

三 自定义频率组件

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 相关文章推荐
python根据距离和时长计算配速示例
Feb 16 Python
python django 访问静态文件出现404或500错误
Jan 20 Python
python 接口返回的json字符串实例
Mar 27 Python
python 重命名轴索引的方法
Nov 10 Python
详解django自定义中间件处理
Nov 21 Python
Flask框架实现的前端RSA加密与后端Python解密功能详解
Aug 13 Python
Python 基于wxpy库实现微信添加好友功能(简洁)
Nov 29 Python
python自动识别文本编码格式代码
Dec 26 Python
PyTorch笔记之scatter()函数的使用
Feb 12 Python
python 实现多维数组(array)排序
Feb 28 Python
pycharm实现在子类中添加一个父类没有的属性
Mar 12 Python
python模拟哔哩哔哩滑块登入验证的实现
Apr 24 Python
Python的UTC时间转换讲解
Feb 26 #Python
Python逐行读取文件中内容的简单方法
Feb 26 #Python
Python计算时间间隔(精确到微妙)的代码实例
Feb 26 #Python
python3编写ThinkPHP命令执行Getshell的方法
Feb 26 #Python
初探利用Python进行图文识别(OCR)
Feb 26 #Python
Python编写合并字典并实现敏感目录的小脚本
Feb 26 #Python
Python实现监控Nginx配置文件的不同并发送邮件报警功能示例
Feb 26 #Python
You might like
PHP error_log()将错误信息写入一个文件(定义和用法)
2013/10/25 PHP
PHP永久登录、记住我功能实现方法和安全做法
2015/04/27 PHP
YII Framework框架教程之日志用法详解
2016/03/14 PHP
PHP简单预防sql注入的方法
2016/09/27 PHP
PHP设计模式之工厂模式实例总结
2017/09/01 PHP
ThinkPHP5与单元测试PHPUnit使用详解
2020/02/23 PHP
JavaScript之appendChild、insertBefore和insertAfter使用说明
2010/12/30 Javascript
通过JQuery实现win8一样酷炫的动态磁贴效果(示例代码)
2013/07/13 Javascript
AngularJS过滤器详解及示例代码
2016/08/16 Javascript
理解AngularJs篇:30分钟快速掌握AngularJs
2016/12/23 Javascript
jQuery实现的分页功能示例
2017/01/22 Javascript
bootstrap fileinput组件整合Springmvc上传图片到本地磁盘
2017/05/11 Javascript
js自定义弹框插件的封装
2020/08/24 Javascript
Angular使用Md5加密的解决方法
2017/09/16 Javascript
详解小程序设置缓存并且不覆盖原有数据
2019/04/15 Javascript
微信小程序实现搜索历史功能
2020/03/26 Javascript
vue-cli脚手架的.babelrc文件用法说明
2020/09/11 Javascript
[02:02]2018DOTA2亚洲邀请赛Mineski赛前采访
2018/04/04 DOTA
[19:26]TNC vs EG (BO3)
2018/06/07 DOTA
[11:44]Ti9 OG夺冠时刻
2019/08/25 DOTA
python 开发的三种运行模式详细介绍
2017/01/18 Python
python字符串中的单双引
2017/02/16 Python
python email smtplib模块发送邮件代码实例
2018/04/26 Python
在python2.7中用numpy.reshape 对图像进行切割的方法
2018/12/05 Python
详解python中的index函数用法
2019/08/06 Python
python实现学生通讯录管理系统
2021/02/25 Python
浅析与CSS3的loading动画加载相关的transition优化
2015/05/18 HTML / CSS
金宝贝童装官网:Gymboree
2016/08/31 全球购物
以色列的身体护理及家居香薰品牌:Sabon NYC
2018/02/23 全球购物
Zipadee-Zip襁褓过渡毯:Sleeping Baby
2018/12/30 全球购物
季度思想汇报
2014/01/01 职场文书
索桥的故事教学反思
2014/02/06 职场文书
聘用意向书范本
2014/04/01 职场文书
团委书记的竞聘演讲稿
2014/04/24 职场文书
调解协议书范本
2016/03/21 职场文书
springboot应用服务启动事件的监听实现
2022/04/06 Java/Android