DRF-Throttle组件源码分析及改编源码
1. 限流组件源码分析
注意:以下源码为方便理解已进行简化,只保留了与限流组件相关的代码。注释前的数字代表执行顺序。


SimpleRateThrottle类的源码解析:

2. 实践:编写一个限流类
from rest_framework.throttling import SimpleRateThrottle
from django.core.cache import cache as default_cache
class IpThrottle(SimpleRateThrottle):
scope = "ip" # 节流类的名称
# THROTTLE_RATES = {"x1": "5/m"} 类中未定义THROTTLE_RATES则去settings中获取
cache = default_cache # 节流类指定写入的缓存
def get_cache_key(self, request, view):
ident = self.get_ident(request) # 获取请求用户IP(去request中找请求头)
return self.cache_format % {'scope': self.scope, 'ident': ident}
class UserThrottle(SimpleRateThrottle):
scope = "user" # 节流类的名称
# THROTTLE_RATES = {"x1": "5/m"} 类中未定义THROTTLE_RATES则去settings中获取
cache = default_cache # 节流类指定写入的缓存
def get_cache_key(self, request, view):
ident = request.user.pk # 用户ID
return self.cache_format % {'scope': self.scope, 'ident': ident}
3. 源码改编
- 重写限流的时长规则:原本只支持 1分钟x次,重写后支持 x分钟x次:
def parse_rate(self, rate):
'''重写获取时长的parse_rate方法,原本只能写1/m或2/m,现在支持:1/5m, 3/10m的格式'''
if rate is None:
return (None, None)
num, period = rate.split('/') # "1/5m"
num_requests = int(num)
duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[-1]]
count = int(period[0:-1])
return (num_requests, duration * count)
- 请求操作失败时,不计入限流次数
# 思路:在视图的操作成功后再进行计入操作(throttle_success)
# 限流类中: 重写throttle_success操作,并把计次的操作提取出来,自定义一个函数,在视图操作成功后才调用该函数进行计次
class MyThrottle(SimpleRateThrottle):
def throttle_success(self):
# self.history.insert(0, self.now)
# self.cache.set(self.key, self.history, self.duration)
return True
def done(self):
""" 视图函数执行成功后,再调用throttle_success里的方法"""
self.history.insert(0, self.now)
self.cache.set(self.key, self.history, self.duration)
# 视图类中:
class MyView(APIView):
def post(request):
"""中间代码省略"""
# 成功操作后才记录一次限流
for throttle in self.get_throttles():
throttle.done()
- 自定义限流类的报错信息
# 在限流类中:
# 自定义抛出报错的异常类
class ThrottledException(exceptions.APIException):
status_code = status.HTTP_429_TOO_MANY_REQUESTS
default_code = 'throttled'
#重写throttle_failure方法,自定义报错信息并直接抛出异常;
def throttle_failure(self):
wait = self.wait()
detail = {
"code": return_code.TOO_MANY_REQUESTS,
"data": "访问频率限制",
'detail': "需等待{}秒后才能访问".format(int(wait))
}
raise ThrottledException(detail)
DRF-Throttle组件源码分析及改编源码的更多相关文章
- drf的基本使用、APIView源码分析和CBV源码拓展
cbv源码拓展 扩展,如果我在Book视图类中重写dispatch方法 -可以实现,在get,post方法执行之前或者之后执行代码,完成类似装饰器的效果 def dispatch(self, requ ...
- NIO 源码分析(05) Channel 源码分析
目录 一.Channel 类图 二.begin 和 close 是什么 2.1 AbstractInterruptibleChannel 中的 begin 和 close 2.2 Selector 中 ...
- NIO 源码分析(02-2) BIO 源码分析 Socket
目录 一.BIO 最简使用姿势 二.connect 方法 2.1 Socket.connect 方法 2.2 AbstractPlainSocketImpl.connect 方法 2.3 DualSt ...
- NIO 源码分析(02-1) BIO 源码分析
目录 一.BIO 最简使用姿势 二.ServerSocket 源码分析 2.1 相关类图 2.2 主要属性 2.3 构造函数 2.4 bind 方法 2.5 accept 方法 2.6 总结 NIO ...
- [源码分析] 从实例和源码入手看 Flink 之广播 Broadcast
[源码分析] 从实例和源码入手看 Flink 之广播 Broadcast 0x00 摘要 本文将通过源码分析和实例讲解,带领大家熟悉Flink的广播变量机制. 0x01 业务需求 1. 场景需求 对黑 ...
- Spring Ioc源码分析系列--Ioc源码入口分析
Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...
- k8s client-go源码分析 informer源码分析(3)-Reflector源码分析
k8s client-go源码分析 informer源码分析(3)-Reflector源码分析 1.Reflector概述 Reflector从kube-apiserver中list&watc ...
- 5.2 spring5源码--spring AOP源码分析三---切面源码分析
一. AOP切面源码分析 源码分析分为三部分 1. 解析切面 2. 创建动态代理 3. 调用 源码的入口 源码分析的入口, 从注解开始: 组件的入口是一个注解, 比如启用AOP的注解@EnableAs ...
- jQuery1.11源码分析(1)-----Sizzle源码概览[原创]
最近在啃jQuery1.11源码,上来就遇到Sizzle这个jQuery的大核心,虽然已经清楚了Sizzle的用途,先绕过去也没事,但明知山有虎偏向虎山行才是我们要做的. 本文面向的阅读对象:正在学习 ...
- 【MyBatis源码分析】select源码分析及小结
示例代码 之前的文章说过,对于MyBatis来说insert.update.delete是一组的,因为对于MyBatis来说它们都是update:select是一组的,因为对于MyBatis来说它就是 ...
随机推荐
- 结果集为List如何转为Map<String,List<Entity>>?
普通写法 Map<String, List<Model>> map = new HashMap<>();// 如何获取相同的num 的对象做运算 for (Mode ...
- 【CMake系列】10-cmake测试 ctest
cmake作为一个强大的构建系统指导工具,同时也提供了测试功能,可用于项目的单元测试等,也可以与其他测试框架协作,如googletest,共同完成项目开发中的测试工作,本节我们就来学习 如何借助cma ...
- ubuntu16.04/CentOS 7自动以root身份登录桌面
ubuntu16.04 1.首先设置root用户密码: # sudo passwd root 输入普通用户密码,再输入root用户密码: 2.启用登录时的root选项: # 编辑50-ubuntu.c ...
- Zabbix创建模板(templates)及监控项(item)
Zabbix监控--Zabbix创建模板(templates)及监控项(item) 生产环境中,有一个简单的原则,那就是无监控不上线,监控系统开源方案中,zabbix也算不错的选择.由于其系统接口的开 ...
- Docker容器暴露ip至外网
参考地址:https://blog.csdn.net/lvshaorong/article/details/69950694
- Flutter调试debug或者打包release帧率只有60的原因
问题描述 最近发现Flutter中引入像素较大的静态图片或者字体导致调试或者打包之后在高刷手机上帧率只有60的问题. 测试设备为小米13,可在开发者选项中直接打开帧率显示, 也可使用statsfl插件 ...
- 以太坊Rollup方案之 arbitrum(1)
什么是Rollup? 以太坊的Rollup扩容是一种Layer 2(第二层)扩容解决方案,旨在提高以太坊区块链的交易吞吐量和性能.它通过将大量的交易数据转移到以太坊区块链之外的第二层网络来实现这一目标 ...
- VS code常用插件安装【持续更新】
Auto Close Tag 自动添加HTML/XML关闭标签.例如,在输入<div>时,输入完最后一个尖括号>时,会自动添加对应的闭合标签</div> Auto Ren ...
- Time Zone, Leap Year, Date Format, Epoch Time 时区, 闰年, 日期格式
前言 以前有写过一篇了, 但很乱, 这篇就作为它的整理版吧. Leap Year 闰年 闰年是指那些有 366 天, 二月份有 29号 的年份. 比如 2020年 有 2月29日, 所以 2020 就 ...
- BOM – Navigator SendBeacon
介绍 游览器专门做给 tracking 用的接口. 从前我们想 tracking 用户点击 anchor 是比较麻烦的. 因为 click 事件触发后, 想发 ajxax 去做 tracking re ...