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保存字符串到文件的方法
Jul 01 Python
Python中operator模块的操作符使用示例总结
Jun 28 Python
Python下的Softmax回归函数的实现方法(推荐)
Jan 26 Python
python正则表达式的使用
Jun 12 Python
python在ubuntu中的几种安装方法(小结)
Dec 08 Python
python中使用xlrd读excel使用xlwt写excel的实例代码
Jan 31 Python
python实现beta分布概率密度函数的方法
Jul 08 Python
利用python实现短信和电话提醒功能的例子
Aug 08 Python
python requests模拟登陆github的实现方法
Dec 26 Python
VSCode配合pipenv搞定虚拟环境的实现方法
May 17 Python
Pycharm的Available Packages为空的解决方法
Sep 18 Python
详解pytorch创建tensor函数
Mar 22 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
《DOTA3》开发工作已经开始 《DOTA3》将代替《DOTA2》
2021/03/06 DOTA
url decode problem 解决方法
2011/12/26 PHP
PHP中echo,print_r与var_dump区别分析
2014/09/29 PHP
thinkPHP5.0框架环境变量配置方法
2017/03/17 PHP
动态表单验证的操作方法和TP框架里面的ajax表单验证
2017/07/19 PHP
JavaScript 编程引入命名空间的方法与代码
2007/08/13 Javascript
利用js正则表达式验证手机号,email地址,邮政编码
2014/01/23 Javascript
js判断鼠标位置是否在某个div中的方法
2016/02/26 Javascript
基于Bootstrap使用jQuery实现简单可编辑表格
2016/05/04 Javascript
ExtJs使用自定义插件动态保存表头配置(隐藏或显示)
2018/09/25 Javascript
IE8中jQuery.load()加载页面不显示的原因
2018/11/15 jQuery
微信小程序城市选择及搜索功能的方法
2019/03/22 Javascript
vue实现后台管理权限系统及顶栏三级菜单显示功能
2019/06/19 Javascript
Vue-cli3项目引入Typescript的实现方法
2019/10/18 Javascript
跟老齐学Python之for循环语句
2014/10/02 Python
Python中统计函数运行耗时的方法
2015/05/05 Python
python连接数据库的方法
2017/10/19 Python
wx.CheckBox创建复选框控件并响应鼠标点击事件
2018/04/25 Python
django中模板的html自动转意方法
2018/05/27 Python
python读取excel指定列数据并写入到新的excel方法
2018/07/10 Python
django+mysql的使用示例
2018/11/23 Python
在python3中pyqt5和mayavi不兼容问题的解决方法
2019/01/08 Python
Django操作session 的方法
2020/03/09 Python
手把手教你配置JupyterLab 环境的实现
2021/02/02 Python
css3实现画半圆弧线的示例代码
2017/11/06 HTML / CSS
html5 利用canvas实现超级玛丽简单动画
2013/09/06 HTML / CSS
HTML5 表单验证失败的提示语问题
2017/07/13 HTML / CSS
俄罗斯天然和有机产品、健康生活网上商店:Fitomarket.ru
2020/10/09 全球购物
Levi’s西班牙官方网站:李维斯,著名的牛仔裤品牌
2020/08/20 全球购物
档案管理员岗位职责
2013/12/01 职场文书
心理健康教育心得体会
2013/12/29 职场文书
护士辞职信模板
2014/01/20 职场文书
预备党员考察意见范文
2015/06/01 职场文书
2015年党务工作者个人工作总结
2015/10/22 职场文书
JS新手入门数组处理的实用方法汇总
2021/04/07 Javascript
java代码实现空间切割
2022/01/18 Java/Android