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 相关文章推荐
TensorFlow变量管理详解
Mar 10 Python
Python实现注册、登录小程序功能
Sep 21 Python
python元组的概念知识点
Nov 19 Python
对tensorflow中cifar-10文档的Read操作详解
Feb 10 Python
pycharm 中mark directory as exclude的用法详解
Feb 14 Python
Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作
Jun 06 Python
完美解决keras 读取多个hdf5文件进行训练的问题
Jul 01 Python
Pycharm 2020.1 版配置优化的详细教程
Aug 07 Python
python中random.randint和random.randrange的区别详解
Sep 20 Python
15个应该掌握的Jupyter Notebook使用技巧(小结)
Sep 23 Python
基于PyTorch实现一个简单的CNN图像分类器
May 29 Python
简单且有用的Python数据分析和机器学习代码
Jul 02 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
escape unescape的php下的实现方法
2007/04/27 PHP
PHP实现的简单AES加密解密算法实例
2017/05/29 PHP
Thinkphp5框架实现获取数据库数据到视图的方法
2019/08/14 PHP
PHP操作Redis常用命令的实例详解
2020/12/23 PHP
动态添加js事件实现代码
2009/03/12 Javascript
jQuery实现单行文字间歇向上滚动源代码
2013/06/02 Javascript
NodeJS与Mysql的交互示例代码
2013/08/18 NodeJs
jquery text(),val(),html()方法区别总结
2013/11/04 Javascript
关于JavaScript命名空间的一些心得
2014/06/07 Javascript
jquery 操作css样式、位置、尺寸方法汇总
2014/11/28 Javascript
javascript使用Promise对象实现异步编程
2016/03/01 Javascript
JavaScript中两个字符串的匹配
2016/06/08 Javascript
Angular实现点击按钮后在上方显示输入内容的方法
2017/12/27 Javascript
解决vue页面刷新或者后退参数丢失的问题
2018/03/13 Javascript
Vuex实现数据共享的方法
2019/12/20 Javascript
[01:04:22]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 IG vs EG
2018/04/01 DOTA
跟老齐学Python之赋值,简单也不简单
2014/09/24 Python
Python中的True,False条件判断实例分析
2015/01/12 Python
对python list 遍历删除的正确方法详解
2018/06/29 Python
django+echart绘制曲线图的方法示例
2018/11/26 Python
Python图像处理之图片文字识别功能(OCR)
2019/07/30 Python
python opencv将表格图片按照表格框线分割和识别
2019/10/30 Python
宝塔面板成功部署Django项目流程(图文)
2020/06/22 Python
Html5如何唤起百度地图App的方法
2019/01/27 HTML / CSS
香港太阳眼镜网上商店:SmartBuyGlasses香港
2016/07/22 全球购物
澳大利亚在线家具、灯饰和家居装饰店:LivingStyles
2018/11/20 全球购物
英国家居装饰品、户外家具和玻璃器皿购物网站:Rinkit.com
2019/11/04 全球购物
Yahoo的PHP面试题
2014/05/26 面试题
酒店总经理职务说明书
2014/02/26 职场文书
预备党员表决心书
2014/03/11 职场文书
小学毕业典礼主持词
2014/03/27 职场文书
买卖合同纠纷代理词
2015/05/25 职场文书
火烧圆明园观后感
2015/06/03 职场文书
培训班开班主持词
2015/07/02 职场文书
学校标语口号大全
2015/12/26 职场文书
浅谈哪个Python库才最适合做数据可视化
2021/06/28 Python