BaseThrottle

(1) 取出访问者ip
(2) 判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
(3) 循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
(4) 判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
(5) 当大于等于3,说明一分钟内访问超过三次,返回False验证失败

1、分发display

def dispatch(self, request, *args, **kwargs):try:# 进入初始化self.initial(request, *args, **kwargs)

2、 drf初始化方法

APIview下的方法
def initial(self, request, *args, **kwargs):# 认证self.perform_authentication(request)# 进入权限self.check_permissions(request)# --> 频率self.check_throttles(request)

3、频率模块

def check_throttles(self, request):"""Check if request should be throttled.Raises an appropriate exception if the request is throttled."""# 循环的是列表for throttle in self.get_throttles():# 返回结果true or false, false就继续执行if not throttle.allow_request(request, self):# 视图类的三个参数, self, request,  # throttle.wait(): 最后wait返回的数字self.throttled(request, throttle.wait())

3.1、for throttle in self.get_throttles():

def get_throttles(self):"""Instantiates and returns the list of throttles that this view uses."""# 跟权限组件一样, 这里循环 return出去的也是一个列表return [throttle() for throttle in self.throttle_classes]

3.2、if 判断

# 当返回为false时,说明该用户或订单无此权限,
# not false为true 继续往下执行, not true就是 false, 不执行下面代码
if not throttle.allow_request(request, self):

3.3、throttle.allow_request

# 如果是false 就直接返回这个错误了
def allow_request(self, request, view):"""Return `True` if the request should be allowed, `False` otherwise."""raise NotImplementedError('.allow_request() must be overridden')

4、BasePermission

# 继承基础的认证权限, 如果忘了要定义哪个类 直接在这里看也OKfrom rest_framework.throttling import BaseThrottle# 自定义的组件def allow_request(self, request, view):raise NotImplementedError('.allow_request() must be overridden')def get_ident(self, request):xff = request.META.get('HTTP_X_FORWARDED_FOR')remote_addr = request.META.get('REMOTE_ADDR')num_proxies = api_settings.NUM_PROXIESif num_proxies is not None:if num_proxies == 0 or xff is None:return remote_addraddrs = xff.split(',')client_addr = addrs[-min(num_proxies, len(addrs))]return client_addr.strip()return ''.join(xff.split()) if xff else remote_addr# 最后要返回的时间或者其它def wait(self):return None

5、定义一个权限

class MyPermission(BasePermission):# 前台返回的错误message = "您没有权限, 请先联系下管理员增加权限"# 获取权限def has_permission(self,request, view):# 认证组件, 返回的request.userprint("permission: ", request.user.permission)if request.user.permission > 1:# 如果大于就是true, 在第3步,if not true 等于false就不执行它了return Truereturn False

6、频率组件

class FirstThrottle(BaseThrottle):get_ip = {}def __init__(self):self.history = Noneself.ip = Noneself.ctime = time.time()def allow_request(self, request, view)::param request: 浏览器请求过来的数据:param view: apiview视图:return: true or false# 1、取出访问者的IPclient_ip = request.META.get("REMOTE_ADDR")self.ip = client_ip# 2、判断不存在的话添加到字典 并将时间也一并添加进去if client_ip not in self.get_ip:self.get_ip[client_ip] = [self.ctime, ]return True# 获取当前IP的访问时间记录self.history = self.get_ip[client_ip]# 3、 开始循环判断, 如果最后一个大于60秒就直接干掉while self.history and self.ctime - self.history[-1] > 60:self.history.pop()if len(self.history) < 3:self.history.insert(0, self.ctime)return Truereturn Falsedef wait(self):last_time = self.ctime - self.history[-1] - 10if last_time == 0:self.get_ip[self.ip].clear()return last_time

7、全局使用频率

# settings.py文件中定义, 所有的组件都可以放在这里REST_FRAMEWORK = {"DEFAULT_THROTTLE_CLASSES": ['app01.myauth.FirstThrottle',  # 全局使用权限]
}

7、局部使用

类中直接使用 throttle_classes = [FirstThrottle, ]

8、局部禁用

类中直接使用 throttle_classes = []

SimpleRateThrottle

使用组件中自带的频率控制组件

先在settings.py中定义限制频率的范围
REST_FRAMEWORK={"DEFAULT_THROTTLE_RATES": {"thro_rate": "10/m"}
}

1、进入频率

class SimpleRateThrottle(BaseThrottle):cache = default_cache# 获取时间timer = time.timecache_format = 'throttle_%(scope)s_%(ident)s'# 这个是在setting中设置的 DEFAULT_THROTTLE_RATES的字典key, 必须得定义scope = NoneTHROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATES# 初始化,def __init__(self):# 首先就是先判断 rate是否为空, 如果是false为空,就进入self.get_rate if not getattr(self, 'rate', None):# 直接输出错误self.rate = self.get_rate()# 如果上一步通过,就继续进入这里 9.2    self.num_requests, self.duration = self.parse_rate(self.rate)# 也就是说执行完9.2之后 获取到的结果就是# self.num_requests, self.duration = (10,60)

1.1、get_rate

def get_rate(self):# scope 这个值在类中必须被定义成 settings中定义的值 如thro_rateif not getattr(self, 'scope', None):msg = ("You must set either `.scope` or `.rate` for '%s' throttle" %self.__class__.__name__)raise ImproperlyConfigured(msg)try:# 在配置文件中 将thro_rate 取出, 返回 10/mreturn self.THROTTLE_RATES[self.scope]except KeyError:msg = "No default throttle rate set for '%s' scope" % self.scoperaise ImproperlyConfigured(msg)

2、当初始化通过

​ self.num_requests, self.duration = self.parse_rate(self.rate)

def parse_rate(self, rate):"""Given the request rate string, return a two tuple of:<allowed number of requests>, <period of time in seconds>"""# 这个是在setting中设置的 DEFAULT_THROTTLE_RATES的字典设置为空,就直接返回none,noneif rate is None:return (None, None)# 这里的rate就是就是get_rate取出来的10/m 然后切割它num, period = rate.split('/')num_requests = int(num)# 定义如果是m就是60秒,然后字典中直接取值这里是m取出来的就是60duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]# 最后返回它俩return (num_requests, duration)

3、类中调用get_cache_key

def get_cache_key(self, request, view):"""# 应返回可用于限制的唯一缓存键。Should return a unique cache-key which can be used for throttling.# 必须要重写, 否则调用SimpleRateThrottle也会直接报错Must be overridden.May return `None` if the request should not be throttled."""raise NotImplementedError('.get_cache_key() must be overridden')

4、实例

class FirstThrottle(SimpleRateThrottle):# 这里会调用 self.get_rate那个函数,返回的就是 10/m了scope = "thro_rate"# 如果不重新定义就会报错, 因为它得从缓存中找出 ip地址def get_cache_key(self, request, view):# 返回空也行, 也会有倒计时return self.get_ident(request)# "detail": "Request was throttled. Expected available in 56 seconds."

5、中文显示错误日志

5.1、流程的前3步

def check_throttles(self, request):"""Check if request should be throttled.Raises an appropriate exception if the request is throttled."""for throttle in self.get_throttles():if not throttle.allow_request(request, self):# 如果不存在 就进入到 throttled中self.throttled(request, throttle.wait())

5.2、throttled 错误提示

def throttled(self, request, wait):"""If request is throttled, determine what kind of exception to raise."""# 返回错误信息raise exceptions.Throttled(wait)

5.3、重写exceptions方法

class Throttled(APIException):status_code = status.HTTP_429_TOO_MANY_REQUESTSdefault_detail = _('Request was throttled.')extra_detail_singular = 'Expected available in {wait} second.'extra_detail_plural = 'Expected available in {wait} seconds.'

5.4、实例

from app01.SelfThrottle import FirstThrottle
from rest_framework import exceptionsclass Thor(APIView):# 局部使用throttle_classes = [FirstThrottle, ]def get(self, request, *args, **kwargs):return HttpResponse("ok")# 需要注意的是 这里需要在视图类的重写方法,或继承def throttled(self, request, wait):class Myerrors(exceptions.Throttled):default_detail = "超出频率限制"extra_detail_singular = '请 {wait} 秒后在访问.'extra_detail_plural = '请 {wait} 秒后在访问.'raise Myerrors(wait)

转载于:https://blog.51cto.com/xiong51/2395173

python_restframework(频率组件)相关推荐

  1. Django框架之DRF 认证组件源码分析、权限组件源码分析、频率组件源码分析

    阅读目录 认证组件 权限组件 频率组件 认证组件 权限组件 频率组件

  2. Django框架深入了解_03(DRF之认证组件、权限组件、频率组件、token)

    阅读目录 一.认证组件 使用方法: token简单描述: 应用token编写登录接口: 二.权限组件 使用方法: 三.频率组件 使用方法: 一.认证组件 回到顶部 使用方法: ①写一个认证类,新建文件 ...

  3. Django REST framework 认证、权限和频率组件

    认证与权限频率组件 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能 ...

  4. Rest_Framework之频率组件部分

    一.RestFramework之频率组件源码部分 频率组件的源码部分和权限组件流程一模一样的,这里就不多说了,直接上源码的主要逻辑部分: def check_throttles(self, reque ...

  5. drf 频率组件 META字典详情

    drf频率组件 什么是频率 控制用户对某个url的请求频率,比如一分钟之内,只能访问三次 自定义频率规则 1.取出访问者ip 2.判断当前ip在不在访问字典中:不在,则添加进去,返回True; 3.循 ...

  6. drf6 权限和频率控制组件

    对某件事情决策的范围和程度,我们叫做权限,权限是我们在项目开发中非常常用到的. DRF框架给我们提供的权限组件 权限组件 之前DRF的版本和认证,知道了权限和频率跟版本认证都是在initial方法里初 ...

  7. drf5 版本和认证组件

    开发项目是有多个版本的 随着项目的更新,版本就越来越多.不可能新的版本出了,以前旧的版本就不进行维护了 那我们就需要对版本进行控制,这个DRF框架也给我们提供了一些封装好的版本控制方法 版本控制组件 ...

  8. 04,认证、权限、频率

    认证组件 Django原生的authentic组件为我们的用户注册与登录提供了认证功能,十分的简介与强大.同样DRF也为我们提供了认证组件,一起来看看DRF里面的认证组件是怎么为我们工作的! mode ...

  9. django Rest Framework----认证/访问权限控制/访问频率限制 执行流程 Authentication/Permissions/Throttling 源码分析...

    url: url(r'books/$',views.BookView.as_view({'get':'list','post':'create'})) 为例 当django启动的时候,会调用执行vie ...

最新文章

  1. 闪灯什么意思_开车闪一下闪二下闪三下大灯是什么意思
  2. C++在数字向量中找到出现奇数次的数字的算法实现(附完整源码)
  3. 出现503错误 怎么办
  4. 冒泡排序的双重循环理解
  5. C#入门,基本的整型输入
  6. lintcode:合并排序数组
  7. 【转】WCF与Web API 区别(应用场景)
  8. [asp.net] 验证控件的属性及用法
  9. matlab斜杠报错,java调用matlab 时出现java.lang.NullPointerException错误
  10. JavaScript and CSS
  11. 在ntpdate同步时间的时候出现“the NTP socket is in use, exiting”
  12. 机器学习- 吴恩达Andrew Ng Week1 知识总结 Introduciton
  13. Latex 公式速查
  14. Activemq 下载地址
  15. Matlab一张图上绘制两条曲线-2021-11-05
  16. 远程监控养猪监控系统
  17. Java HashMap双花括号初始化数据的代码解析,及带来的问题分析
  18. 使用WindowsLiveWriter发布51cto博客
  19. Speedoffice(excel)如何自动换行
  20. MySQL中 反引号、单引号 和 双引号 的区别

热门文章

  1. 为了孩子上名校,他们发论文给子女署名,Nature发文报道韩国学术不当行为
  2. mynginx.conf
  3. 【AR】开始使用Vuforia开发iOS(2)
  4. JdbcTemplate(1)(数据连接池)
  5. 始于《将才》,而不止于将才
  6. 人工智能AI-机器视觉CV-数据挖掘DM-机器学习ML-神经网络-[资料集合贴]
  7. Almost sorted interval
  8. DNS与Active Directory在两台服务器分别布署
  9. python若干整数的最大值_实例讲解Python中整数的最大值输出
  10. 5G 标准 — R18