Django Rest framework频率原理与限制


Posted in Python onJuly 26, 2019

前言

开发平台的API接口调用需要限制其频率,以节约服务器资源和避免恶意的频繁调用.

DRF就为我们提供了一些频率限制的方法.

DRF中的版本、认证、权限、频率组件的源码是一个流程,且频率组件在最后执行.

DRF频率组件原理

DRF中的频率控制基本原理是基于访问次数和时间的,当然我们也可以通过自己定义的方法来实现.

当请求进来,走到我们的频率组件时,DRF内部会有一个字典来记录访问者的IP.

以这个字典的IP为key,value为一个列表,存放访问者每次访问的时间:{PI1: [第三次访问时间, 第二次访问时间, 第一次访问时间, ]}

把每次访问的最新时间放入列表的最前面,记录这样一个数据结构后,通过如下方式限制:

如果我们设置的是10秒内只能访问5次:

1.判断访问者的IP是否在这个请求IP的字典里.

2.保证这个列表里都是都是最近10秒内访问的时间.

判断当前请求时间和列表里最早的(也就是最后一个)请求时间差

如果差大于10秒,说明请求不是最近10秒内的,删除掉最后一个

继续判断倒数第二个、第三个,直到差小于10秒为止

3.判断列表的长度(即访问次数)是否大于我们设置的5次.

如果大于,则限制其访问

如果小于,则放行,并把时间记录到列表的最前面

使用自带的频率限制类

首先 配置频率限制类

from rest_framework.throttling import SimpleRateThrottle # 导入内置的频率限制类

class DRFThrottle(SimpleRateThrottle):
  """注意:这里都是必备的属性、方法和返回值"""
  scope = 'WD'
  def get_cache_key(self, request, view):
    # 拿IP地址
    return self.get_ident(request)

然后 配置文件

REST_FRAMEWORK = {
  # 指定频率限制的类
  "DEFAULT_THROTTLE_CLASSES": ['blog.throttle.DRFThrottle'],
  # WD是scope定义的值,3/m表示每分钟不能超过3次访问
  "DEFAULT_THROTTLE_RATES": {"WD": "3/m"},
}

"""
如果只是想给单个视图做频率限制:
则删除这里的"DEFAULT_THROTTLE_CLASSES"配置项
并在要做频率限制的视图中指定频率限制类即可
指定语法:throttle_classes = ["频率限制类", ]
"""

开始测试

访问测试页面,连续刷新3次后,可看到:

Django Rest framework频率原理与限制

使用自定义的频率限制类

首先 自定义频率限制类

import time

VISIT_RECORD = {} # 限制访问次数的字典

class MyThrottle():
  """
  自定义频率限制类,一分钟允许访问5次
  注意:自定义频率限制类中必须要有allow_request和wait方法
  前者用于频率限制的逻辑,后者用于返回限制时间还剩多少秒
  """

  def __init__(self):
    self.history = []

  def allow_request(self, request, view):
    """用于限制访问的逻辑"""
    # 获取用户的IP地址
    ip = request.META.get('REMOTE_ADDR')
    if ip not in VISIT_RECORD:
      VISIT_RECORD[ip] = [time.time(), ]
    else:
      history = VISIT_RECORD[ip]
      self.history = history
      history.insert(0, time.time())
      # 确保访问时间在允许范围之内
      while self.history[0] - self.history[-1] > 60:
        self.history.pop()
      # 确定访问次数在允许的范围内
      if len(self.history) >= 5:
        return False
    return True

  def wait(self):
    """用于返回限制时间还剩多少秒"""
    return 60 - (self.history[0] - self.history[-1])

然后 配置文件

REST_FRAMEWORK = {
  # 指定自定义的频率限制类
  "DEFAULT_THROTTLE_CLASSES": ['blog.throttle.MyThrottle'],
}

> """
如果只是想给单个视图做频率限制:
则删除这里的"DEFAULT_THROTTLE_CLASSES"配置项
并在要做频率限制的视图中指定频率限制类即可
指定语法:throttle_classes = ["频率限制类", ]
"""

好了,就到这里吧.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python中偏函数partial用法实例分析
Jul 08 Python
基于python的Tkinter实现一个简易计算器
Dec 31 Python
深入浅析ImageMagick命令执行漏洞
Oct 11 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
Apr 23 Python
Python实现动态添加属性和方法操作示例
Jul 25 Python
python paramiko利用sftp上传目录到远程的实例
Jan 03 Python
对django2.0 关联表的必填on_delete参数的含义解析
Aug 09 Python
如何关掉pycharm中的python console(图解)
Oct 31 Python
Python使用turtle库绘制小猪佩奇(实例代码)
Jan 16 Python
python_mask_array的用法
Feb 18 Python
tensorflow图像裁剪进行数据增强操作
Jun 30 Python
实例详解Python的进程,线程和协程
Mar 13 Python
Django 使用easy_thumbnails压缩上传的图片方法
Jul 26 #Python
解决django服务器重启端口被占用的问题
Jul 26 #Python
深入解析神经网络从原理到实现
Jul 26 #Python
python单例模式的多种实现方法
Jul 26 #Python
django的ORM操作 增加和查询
Jul 26 #Python
Django在pycharm下修改默认启动端口的方法
Jul 26 #Python
Python解析命令行读取参数之argparse模块
Jul 26 #Python
You might like
关于时间计算的结总
2006/12/06 PHP
PHP中对用户身份认证实现两种方法
2011/06/04 PHP
php中json_encode中文编码问题分析
2011/09/13 PHP
PHP实现模仿socket请求返回页面的方法
2014/11/04 PHP
php在数组中查找指定值的方法
2015/03/17 PHP
PHP实现的二分查找算法实例分析
2017/12/19 PHP
PHP结合Ffmpeg快速搭建流媒体服务的实践记录
2018/10/31 PHP
PHP+Redis链表解决高并发下商品超卖问题(实现原理及步骤)
2020/08/03 PHP
javascript 避免闭包引发的问题
2009/03/17 Javascript
关于viewport,Ext.panel和Ext.form.panel的关系
2009/05/07 Javascript
jQuery each()小议
2010/03/18 Javascript
后台获取ZTREE选中节点的方法
2015/02/12 Javascript
JQuery实现可直接编辑的表格
2015/04/16 Javascript
JS实现的幻灯片切换显示效果
2016/09/07 Javascript
Node.js 利用cheerio制作简单的网页爬虫示例
2018/03/01 Javascript
vue element-ui读取pdf文件的方法
2019/11/26 Javascript
vue中利用three.js实现全景图的完整示例
2020/12/07 Vue.js
js+for循环实现字符串自动转义的代码(把后面的字符替换前面的字符)
2020/12/24 Javascript
python协程用法实例分析
2015/06/04 Python
Linux下通过python访问MySQL、Oracle、SQL Server数据库的方法
2016/04/23 Python
Python3利用SMTP协议发送E-mail电子邮件的方法
2017/09/30 Python
python基础之包的导入和__init__.py的介绍
2018/01/08 Python
Python实现通过继承覆盖方法示例
2018/07/02 Python
python实现AES加密与解密
2019/03/28 Python
Python基于httpx模块实现发送请求
2020/07/07 Python
python实现移动木板小游戏
2020/10/09 Python
python实现MySQL指定表增量同步数据到clickhouse的脚本
2021/02/26 Python
Monnier Frères美国官网:法国知名奢侈品网站
2016/11/22 全球购物
Johnston & Murphy官网: 约翰斯顿·墨菲牛津总统鞋
2018/01/09 全球购物
预订旅游活动、景点和旅游:GetYourGuide
2019/09/29 全球购物
入党自荐书范文
2014/03/09 职场文书
关于学习的演讲稿
2014/05/10 职场文书
庆国庆活动总结
2014/08/28 职场文书
保证书格式
2015/01/16 职场文书
小学生节水倡议书
2015/04/29 职场文书
如何用python绘制雷达图
2021/04/24 Python