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的汉字转GBK码实现代码
Feb 19 Python
python中bisect模块用法实例
Sep 25 Python
python中list常用操作实例详解
Jun 03 Python
python中__call__内置函数用法实例
Jun 04 Python
基于Python3 逗号代码 和 字符图网格(详谈)
Jun 22 Python
Android基于TCP和URL协议的网络编程示例【附demo源码下载】
Jan 23 Python
使用requests库制作Python爬虫
Mar 25 Python
Python中的random.uniform()函数教程与实例解析
Mar 02 Python
解决Pycharm 导入其他文件夹源码的2种方法
Feb 12 Python
postman和python mock测试过程图解
Feb 22 Python
torchxrayvision包安装过程(附pytorch1.6cpu版安装)
Aug 26 Python
python 基于opencv操作摄像头
Dec 24 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中error与exception的区别及应用
2014/07/28 PHP
php实现搜索一维数组元素并删除二维数组对应元素的方法
2015/07/06 PHP
Linux系统下使用XHProf和XHGui分析PHP运行性能
2015/12/08 PHP
实例讲解如何在PHP的Yii框架中进行错误和异常处理
2016/03/17 PHP
php使用文本统计访问量的方法
2016/05/12 PHP
jquery禁止输入数字以外的字符的示例(纯数字验证码)
2014/04/10 Javascript
浅谈angularJS 作用域
2015/07/05 Javascript
AngularJS使用ng-options指令实现下拉框
2016/08/23 Javascript
bootstrap选项卡使用方法解析
2017/01/11 Javascript
JavaScript高阶函数_动力节点Java学院整理
2017/06/28 Javascript
10行原生JS实现文字无缝滚动(超简单)
2018/01/02 Javascript
Node.js 的 GC 机制详解
2019/06/03 Javascript
vue安装遇到的5个报错及解决方法
2019/06/12 Javascript
JavaScript 作用域实例分析
2019/10/02 Javascript
html中创建并调用vue组件的几种方法汇总
2020/11/17 Javascript
python单链表实现代码实例
2013/11/21 Python
python使用any判断一个对象是否为空的方法
2014/11/19 Python
Python内置函数之filter map reduce介绍
2014/11/30 Python
Django 实现下载文件功能的示例
2018/03/06 Python
详解python多线程之间的同步(一)
2019/04/03 Python
OpenCV 边缘检测
2019/07/10 Python
Django 创建/删除用户的示例代码
2019/07/24 Python
Django框架中间件定义与使用方法案例分析
2019/11/28 Python
flask开启多线程的具体方法
2020/08/02 Python
详解CSS 3 中的 calc() 方法
2018/01/12 HTML / CSS
html5 Canvas画图教程(9)—canvas中画出矩形和圆形
2013/01/09 HTML / CSS
选购国际女性时装设计师品牌:IFCHIC(支持中文)
2018/04/12 全球购物
python+selenium小米商城红米K40手机自动抢购的示例代码
2021/03/24 Python
班级寄语大全
2014/04/10 职场文书
法学自荐信
2014/06/20 职场文书
2014年应急管理工作总结
2014/11/26 职场文书
2015年度学校应急管理工作总结
2015/10/22 职场文书
2016年优秀教师先进事迹材料
2016/02/26 职场文书
十一月早安语录:把心放轻,人生就是一朵自在的云
2019/11/04 职场文书
Python基础知识学习之类的继承
2021/05/31 Python
Mysql 设置boolean类型的操作
2021/06/04 MySQL