详解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 continue语句用法实例
Mar 11 Python
python获取当前计算机cpu数量的方法
Apr 18 Python
介绍Python中的fabs()方法的使用
May 14 Python
Python基于socket模块实现UDP通信功能示例
Apr 10 Python
浅谈pandas用groupby后对层级索引levels的处理方法
Nov 06 Python
用python脚本24小时刷浏览器的访问量方法
Dec 07 Python
Python编程在flask中模拟进行Restful的CRUD操作
Dec 28 Python
15行Python代码实现网易云热门歌单实例教程
Mar 10 Python
python格式化输出保留2位小数的实现方法
Jul 02 Python
如何安装并使用conda指令管理python环境
Jul 10 Python
使用python接受tgam的脑波数据实例
Apr 09 Python
浅谈keras中的batch_dot,dot方法和TensorFlow的matmul
Jun 18 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
codeigniter自带数据库类使用方法说明
2014/03/25 PHP
php实现支持中文的文件下载功能示例
2017/08/30 PHP
理解Javascript_12_执行模型浅析
2010/10/18 Javascript
js获取IFRAME当前的URL的方法
2013/11/13 Javascript
Jquery 切换不同图片示例代码
2013/12/05 Javascript
setInterval与clearInterval的使用示例代码
2014/01/28 Javascript
Jquery实现控件的隐藏和显示实例
2014/02/08 Javascript
javascript基于HTML5 canvas制作画箭头组件
2014/06/25 Javascript
一个JavaScript处理textarea中的字符成每一行实例
2014/09/22 Javascript
script标签属性用type还是language
2015/01/21 Javascript
JavaScript获取服务器端时间的方法
2016/11/29 Javascript
彻底解决 webpack 打包文件体积过大问题
2017/07/07 Javascript
浅谈在fetch方法中添加header后遇到的预检请求问题
2017/08/31 Javascript
JS插件clipboard.js实现一键复制粘贴功能
2020/12/04 Javascript
JS实现数组的增删改查操作示例
2018/08/29 Javascript
vue通过style或者class改变样式的实例代码
2018/10/30 Javascript
在 Vue-CLI 中引入 simple-mock实现简易的 API Mock 接口数据模拟
2018/11/28 Javascript
微信小程序页面渲染实现方法
2019/11/06 Javascript
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 KG VS OG
2018/03/30 DOTA
python实现定时播放mp3
2015/03/29 Python
说一说Python logging
2016/04/15 Python
Python中list查询及所需时间计算操作示例
2018/06/21 Python
numpy 计算两个数组重复程度的方法
2018/11/07 Python
Empty test suite.(PyCharm程序运行错误的解决方法)
2018/11/30 Python
解决Python pandas plot输出图形中显示中文乱码问题
2018/12/12 Python
详解Python基础random模块随机数的生成
2019/03/23 Python
Python-copy()与deepcopy()区别详解
2019/07/12 Python
OpenCV Python实现图像指定区域裁剪
2021/03/12 Python
营销主管自我评价怎么写
2013/09/19 职场文书
幼儿园校车司机的岗位职责
2014/01/30 职场文书
函授本科自我鉴定
2014/02/04 职场文书
2014年新生军训方案
2014/05/01 职场文书
音乐课《小猫钓鱼》教学反思
2016/02/18 职场文书
react使用antd的上传组件实现文件表单一起提交功能(完整代码)
2021/06/29 Javascript
深入讲解数据库中Decimal类型的使用以及实现方法
2022/02/15 MySQL
Java实现简单小画板
2022/06/10 Java/Android