详解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 相关文章推荐
打开电脑上的QQ的python代码
Feb 10 Python
分享一下如何编写高效且优雅的 Python 代码
Sep 07 Python
Python基于whois模块简单识别网站域名及所有者的方法
Apr 23 Python
Python使用googletrans报错的解决方法
Sep 25 Python
Python 实现子类获取父类的类成员方法
Jan 11 Python
Django项目之Elasticsearch搜索引擎的实例
Aug 21 Python
python3图片文件批量重命名处理
Oct 31 Python
Tensorflow 卷积的梯度反向传播过程
Feb 10 Python
python pip如何手动安装二进制包
Sep 30 Python
如何解决python多种版本冲突问题
Oct 13 Python
Python3+Flask安装使用教程详解
Feb 16 Python
如何判断pytorch是否支持GPU加速
Jun 01 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使用sql server验证连接数据库的方法
2014/12/25 PHP
PHP字典树(Trie树)定义与实现方法示例
2017/10/09 PHP
PHP实现简易图形计算器
2020/08/28 PHP
javascript之bind使用介绍
2011/10/09 Javascript
jquery提交form表单时禁止重复提交的方法
2014/02/13 Javascript
nodejs URL模块操作URL相关方法介绍
2015/03/03 NodeJs
JS实现的Select三级下拉菜单代码
2015/08/20 Javascript
jquery validate和jquery form 插件组合实现验证表单后AJAX提交
2015/08/26 Javascript
jQuery下拉框的简单应用
2016/06/24 Javascript
Angularjs---项目搭建图文教程
2016/07/08 Javascript
关于数据与后端进行交流匹配(点亮星星)
2016/08/03 Javascript
JS操作input标签属性checkbox全选的实现代码
2017/03/02 Javascript
简单实现js菜单栏切换效果
2017/03/04 Javascript
微信小程序开发之自定义tabBar的实现
2018/09/06 Javascript
Vue.js中对css的操作(修改)具体方式详解
2018/10/30 Javascript
微信小程序时间轴实现方法示例
2019/01/14 Javascript
js函数柯里化的方法和作用实例分析
2020/04/11 Javascript
Node.js利用Express实现用户注册登陆功能(推荐)
2020/10/26 Javascript
python实现人脸识别代码
2017/11/08 Python
使用Python实现微信提醒备忘录功能
2018/12/04 Python
Python 仅获取响应头, 不获取实体的实例
2019/08/21 Python
Django框架反向解析操作详解
2019/11/28 Python
pycharm Tab键设置成4个空格的操作
2021/02/26 Python
蔻驰英国官网:COACH英国
2020/07/19 全球购物
实现中国梦思想汇报2014
2014/09/13 职场文书
党员四风自我剖析材料
2014/10/07 职场文书
后备干部推荐材料
2014/12/24 职场文书
课改心得体会范文
2016/01/25 职场文书
2016护理专业求职自荐书
2016/01/28 职场文书
2016医师资格考试考生诚信考试承诺书
2016/03/25 职场文书
关于考试抄袭的检讨书
2019/11/02 职场文书
导游词之西安大清真寺
2019/12/17 职场文书
Nginx反爬虫策略,防止UA抓取网站
2021/03/31 Servers
浅谈MySQL next-key lock 加锁范围
2021/06/07 MySQL
tomcat下部署jenkins的方法
2022/05/06 Servers
如何用H5实现好玩的2048小游戏
2022/07/23 HTML / CSS