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中使用 Selenium 实现网页截图实例
Jul 18 Python
Python的socket模块源码中的一些实现要点分析
Jun 06 Python
python的变量与赋值详细分析
Nov 08 Python
python求解数组中两个字符串的最小距离
Sep 27 Python
PyCharm配置mongo插件的方法
Nov 30 Python
Python中numpy模块常见用法demo实例小结
Mar 16 Python
浅谈pycharm使用及设置方法
Sep 09 Python
Python阶乘求和的代码详解
Feb 14 Python
SpringBoot实现登录注册常见问题解决方案
Mar 04 Python
python如何发送带有附件、正文为HTML的邮件
Feb 27 Python
在 Golang 中实现 Cache::remember 方法详解
Mar 30 Python
python数字图像处理之对比度与亮度调整示例
Jun 28 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 获取远程文件内容的函数代码
2010/03/24 PHP
php中长文章分页显示实现代码
2012/09/29 PHP
php+ajax导入大数据时产生的问题处理
2014/06/11 PHP
php中chdir()函数用法实例
2014/11/13 PHP
PHP使用memcache缓存技术提高响应速度的方法
2014/12/26 PHP
PHP中创建和验证哈希的简单方法实探
2015/07/06 PHP
php开发微信支付获取用户地址
2015/10/04 PHP
PHP加密解密函数详解
2015/10/28 PHP
PHP实现随机生成水印图片功能
2017/03/22 PHP
Laravel多域名下字段验证的方法
2019/04/04 PHP
JSCode all of Brower 全局屏蔽网页右键功能 具体实现
2013/06/05 Javascript
jQuery异步加载数据并添加事件示例
2014/08/24 Javascript
js获取form的方法
2015/05/06 Javascript
jquery自定义表格样式
2015/11/23 Javascript
jQuery+css实现的时钟效果(兼容各浏览器)
2016/01/27 Javascript
JavaScript实现图片滑动切换的代码示例分享
2016/03/06 Javascript
vue.js中过滤器的使用教程
2017/06/08 Javascript
详解微信小程序 登录获取unionid
2017/06/27 Javascript
javascript获取图片的top N主色值方法详解
2018/01/26 Javascript
原生JS实现的多个彩色小球跟随鼠标移动动画效果示例
2018/02/01 Javascript
JS与jQuery判断文本框还剩多少字符可以输入的方法
2018/09/01 jQuery
JS中使用react-tooltip插件实现鼠标悬浮显示框
2019/05/15 Javascript
Vue分页器实现原理详解
2019/06/28 Javascript
javascript面向对象创建对象的方式小结
2019/07/29 Javascript
JS判断浏览器类型与操作系统的方法分析
2020/04/30 Javascript
vue 获取url里参数的两种方法小结
2020/11/12 Javascript
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
2016/04/12 Python
基于Django contrib Comments 评论模块(详解)
2017/12/08 Python
解决Django数据库makemigrations有变化但是migrate时未变动问题
2018/05/30 Python
详解django中使用定时任务的方法
2018/09/27 Python
使用python接入微信聊天机器人
2020/03/31 Python
Python openpyxl 插入折线图实例
2020/04/17 Python
css3和jquery实现自定义checkbox和radiobox组件
2014/04/22 HTML / CSS
日本最大的旅游网站:Rakuten Travel(乐天旅游)
2018/08/02 全球购物
建筑节能汇报材料
2014/08/22 职场文书
毕业纪念册寄语大全
2015/02/26 职场文书