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 while 循环使用的简单实例
Jun 08 Python
一个基于flask的web应用诞生 用户注册功能开发(5)
Apr 11 Python
Linux RedHat下安装Python2.7开发环境
May 20 Python
Python实现的json文件读取及中文乱码显示问题解决方法
Aug 06 Python
Python中几种属性访问的区别与用法详解
Oct 10 Python
使用python serial 获取所有的串口名称的实例
Jul 02 Python
python通过robert、sobel、Laplace算子实现图像边缘提取详解
Aug 21 Python
Django实现简单网页弹出警告代码
Nov 15 Python
Tensorflow实现在训练好的模型上进行测试
Jan 20 Python
Python闭包与装饰器原理及实例解析
Apr 30 Python
Django生成数据库及添加用户报错解决方案
Oct 09 Python
python数据分析之单因素分析线性拟合及地理编码
Jun 25 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
php搜索文件程序分享
2015/10/30 PHP
PHP常用设计模式之委托设计模式
2016/02/13 PHP
利用php输出不同的心形图案
2016/04/22 PHP
用PHP做了一个领取优惠券活动的示例代码
2019/07/05 PHP
JS判断不同分辨率调用不同的CSS样式文件实现思路及测试代码
2013/01/23 Javascript
了解了这些才能开始发挥jQuery的威力
2013/10/10 Javascript
一个简单的JS时间控件示例代码(JS时分秒时间控件)
2013/11/22 Javascript
jquery+php实现搜索框自动提示
2014/11/28 Javascript
搭建Bootstrap离线文档的方法
2016/12/02 Javascript
JAVA中截取字符串substring用法详解
2017/04/14 Javascript
浅谈struts1 & jquery form 文件异步上传
2017/05/25 jQuery
bootstrap daterangepicker汉化以及扩展功能
2017/06/15 Javascript
使用form-create动态生成vue自定义组件和嵌套表单组件
2019/01/18 Javascript
vue实现鼠标移入移出事件代码实例
2019/03/27 Javascript
Vue+elementui 实现复杂表头和动态增加列的二维表格功能
2019/09/23 Javascript
使用nodejs实现JSON文件自动转Excel的工具(推荐)
2020/06/24 NodeJs
[04:03]2014DOTA2西雅图国际邀请赛 LGD战队巡礼
2014/07/07 DOTA
[01:18]一目了然!DOTA2DotA快捷操作对比第一弹
2014/07/01 DOTA
Python查找相似单词的方法
2015/03/05 Python
python实现应用程序在右键菜单中添加打开方式功能
2017/01/09 Python
Python实现的弹球小游戏示例
2017/08/01 Python
Python应用库大全总结
2018/05/30 Python
python pygame实现五子棋小游戏
2020/10/26 Python
Python程序打包工具py2exe和PyInstaller详解
2019/06/28 Python
Python实现K折交叉验证法的方法步骤
2019/07/11 Python
Python 读取xml数据,cv2裁剪图片实例
2020/03/10 Python
在pycharm创建scrapy项目的实现步骤
2020/12/01 Python
CSS3教程(6):创建网站多列
2009/04/02 HTML / CSS
HTML4和HTML5之间除了相似以外的10个主要不同
2012/12/13 HTML / CSS
联想加拿大官方网站:Lenovo Canada
2018/04/05 全球购物
美国购买韩国护肤和美容产品网站:Althea Korea
2020/11/16 全球购物
工作评语大全
2014/04/26 职场文书
工作收入证明模板
2014/10/10 职场文书
离婚起诉书怎么写
2015/05/19 职场文书
环保建议书范文
2015/09/14 职场文书
SQL实现LeetCode(180.连续的数字)
2021/08/04 MySQL