rest-framework:频率控制
一 频率简介:
为了控制用户对某个url请求的频率,比如,一分钟以内,只能访问三次
二 自定义频率类,自定义频率规则:
自定义的逻辑
#(1)取出访问者ip # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走 # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间, # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过 # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
代码的实现,views.py代码
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.throttling import SimpleRateThrottle,BaseThrottle #第一步,写一个频率类,继承SimpleRateThrottle#重写get_cache_key,返回self.get_ident(request)#一定要记住配置一个scop=字符串 # 第二步:在setting中配置# REST_FRAMEWORK = {# # 'DEFAULT_THROTTLE_RATES':{# 'lxx':'3/m'# }# }class Throttle(SimpleRateThrottle):scope = 'lxx'def get_cache_key(self, request, view):# return request.META.get('REMOTE_ADDR')#返回什么值,就以什么做过滤,返回用户id,就以用户id做过滤return self.get_ident(request)#自定义频率类 class MyThrottle(BaseThrottle):VISIT_RECORD = {}def __init__(self):self.history=Nonedef allow_request(self,request,view):#自定义控制每分钟访问多少次,运行访问返回true,不允许访问返回false# (1)取出访问者ip{ip1:[第二次访问时间,第一次访问时间],ip2:[]}# (2)判断当前ip不在访问字典里,如果不在添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走# (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,# (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过# (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败# (1)取出访问者ip# print(request.META)#取出访问者ipip = request.META.get('REMOTE_ADDR')import time#拿到当前时间ctime = time.time()# (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问if ip not in self.VISIT_RECORD:self.VISIT_RECORD[ip] = [ctime, ]return True#是个当前访问者ip对应的时间列表 [第一次访问的时间,]self.history = self.VISIT_RECORD.get(ip)# (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,while self.history and ctime - self.history[-1] > 60:self.history.pop()# (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过# (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败if len(self.history) < 3:self.history.insert(0, ctime)return Trueelse:return False def wait(self):import timectime = time.time()return 60 - (ctime - self.history[-1])class Books(APIView):# throttle_classes=[Throttle,]
#局部使用throttle_classes=[MyThrottle,] def get(self,request):return Response('')
settings.py中的代码(一分钟访问三次)
REST_FRAMEWORK = {'DEFAULT_THROTTLE_RATES':{'lxx':'3/minute'} }
内置频率限制类:
BaseThrottle是所有类的基类:方法:def get_ident(self, request)获取标识,其实就是获取ip,自定义的需要继承它
AnonRateThrottle:未登录用户ip限制,需要配合auth模块用
SimpleRateThrottle:重写此方法,可以实现频率现在,不需要咱们手写上面自定义的逻辑
UserRateThrottle:登录用户频率限制,这个得配合auth模块来用
ScopedRateThrottle:应用在局部视图上的(忽略)
四 内置频率类及全局使用:
REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES':['自定义频率的方法的路径',],'DEFAULT_THROTTLE_RATES':{'luffy':'3/m'} }
五 源码分析:
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):self.throttled(request, throttle.wait())#以及错误信息的源码 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.'default_code = 'throttled'
错误信息的中文提示:
class Course(APIView):authentication_classes = [TokenAuth, ]permission_classes = [UserPermission, ]throttle_classes = [MyThrottles,]def get(self, request):return HttpResponse('get')def post(self, request):return HttpResponse('post')def throttled(self, request, wait):#自定义中文的错误信息from rest_framework.exceptions import Throttledclass MyThrottled(Throttled):default_detail = '傻逼啊'extra_detail_singular = '还有 {wait} second.'extra_detail_plural = '出了 {wait} seconds.'raise MyThrottled(wait)
class SimpleRateThrottle(BaseThrottle):# 咱自己写的放在了全局变量,他的在django的缓存中cache = default_cache# 获取当前时间,跟咱写的一样timer = time.time# 做了一个字符串格式化,cache_format = 'throttle_%(scope)s_%(ident)s'scope = None# 从配置文件中取DEFAULT_THROTTLE_RATES,所以咱配置文件中应该配置,否则报错THROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATESdef __init__(self):if not getattr(self, 'rate', None):# 从配置文件中找出scope配置的名字对应的值,比如咱写的‘3/m’,他取出来self.rate = self.get_rate()# 解析'3/m',解析成 3 mself.num_requests, self.duration = self.parse_rate(self.rate)# 这个方法需要重写def get_cache_key(self, request, view):"""Should return a unique cache-key which can be used for throttling.Must be overridden.May return `None` if the request should not be throttled."""raise NotImplementedError('.get_cache_key() must be overridden')def get_rate(self):if not getattr(self, 'scope', None):msg = ("You must set either `.scope` or `.rate` for '%s' throttle" %self.__class__.__name__)raise ImproperlyConfigured(msg)try:# 获取在setting里配置的字典中的之,self.scope是 咱写的luffyreturn self.THROTTLE_RATES[self.scope]except KeyError:msg = "No default throttle rate set for '%s' scope" % self.scoperaise ImproperlyConfigured(msg)# 解析 3/m这种传参def parse_rate(self, rate):"""Given the request rate string, return a two tuple of:<allowed number of requests>, <period of time in seconds>"""if rate is None:return (None, None)num, period = rate.split('/')num_requests = int(num)# 只取了第一位,也就是 3/mimmmmmmm也是代表一分钟duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]return (num_requests, duration)# 逻辑跟咱自定义的相同def allow_request(self, request, view):"""Implement the check to see if the request should be throttled.On success calls `throttle_success`.On failure calls `throttle_failure`."""if self.rate is None:return Trueself.key = self.get_cache_key(request, view)if self.key is None:return Trueself.history = self.cache.get(self.key, [])self.now = self.timer()# Drop any requests from the history which have now passed the# throttle durationwhile self.history and self.history[-1] <= self.now - self.duration:self.history.pop()if len(self.history) >= self.num_requests:return self.throttle_failure()return self.throttle_success()# 成功返回true,并且插入到缓存中def throttle_success(self):"""Inserts the current request's timestamp along with the keyinto the cache."""self.history.insert(0, self.now)self.cache.set(self.key, self.history, self.duration)return True# 失败返回falsedef throttle_failure(self):"""Called when a request to the API has failed due to throttling."""return Falsedef wait(self):"""Returns the recommended next request time in seconds."""if self.history:remaining_duration = self.duration - (self.now - self.history[-1])else:remaining_duration = self.durationavailable_requests = self.num_requests - len(self.history) + 1if available_requests <= 0:return Nonereturn remaining_duration / float(available_requests)
-查找顺序:先从自己类中找-----》项目setting配置文件中找-----》drf默认的里面找
转载于:https://www.cnblogs.com/HUIWANG/p/11133083.html
rest-framework:频率控制相关推荐
- Rest Framework:五、不存数据库认证以及自定义 ,内置频率控制类的使用,解析器...
一.不存数据库的认证 环境: 与上次(Rest Framework:四)数据库连接的一致,数据也一致,这次也使用的是上次的django环境 urls.py url(r'^login/', views. ...
- Django REST framework 1
Django REST framework Django REST framework官方文档:点击 中文文档:点击 安装djangorestframework:pip3 install djang ...
- Django Rest framework (看完直接上手用)
Restframework DjangoRestframework 主要使用 APIView 类,其 APIView 实质是对 View 进行继承加工了更多功能 请求进来 APIView() 首先执行 ...
- Django REST framework学习笔记
文章目录 1. API接口开发 1.1 获取数据的接口 1.2 添加数据的接口 1.3 更新数据的接口 1.4 删除数据的接口 2. API字段的定制 2.1 别名字段 2.2 字段格式化 2.3 字 ...
- 关于Django+Framework的最完整面试题(2)
文章目录 一.框架对比 1.Django.Flask.Tornado框架对比 2. WSGI / uwsgi/ uWSGI区分 二.Django框架 3.介绍一下FBV和CBV 4.如何给CBV的程序 ...
- Tengine Framework基础
Tengine Framework基础 最受开发者喜爱的边缘AI计算框架 Tengine是OPEN AI LAB推出的自主知识产权的边缘AI计算框架,致力于解决AIoT产业链碎片化问题,加速AI产业化 ...
- EF-Entity Framework 相关技术点收集贴
不定期.偶尔.添加更新 在网络上看到或者自己开发过程中碰到的EF-Entity Framework相关技术点 本文地址:http://www.cnblogs.com/vnii/archive/2012 ...
- FPGA(4)晶振与计数器 -- 实现定时器(led定时闪烁、蜂鸣器频率控制(单响)、蜂鸣器报警(频带控制,多响))
目录 一.FPGA的晶振与定时器 二.定时器(led闪烁.蜂鸣器频率控制) 1.时钟上升沿.复位下降沿触发 2.复位,计数器清零 3.计数满1s时,计数器清零 4-1.led闪烁(每秒) 4-2.蜂鸣 ...
- Qt Installer Framework实战
Qt Installer Framework是Qt发布的安装程序支持框架,只需要简单的配置就可以生成安装文件,同时可以通过javascript脚本来定制安装过程. 目录结构 config packag ...
- 在虚拟机中 windows 2003 装.net framework 3.5 出现问题.
错误信息: [11/27/09,08:52:50] Microsoft .NET Framework 2.0a: [2] Error: Installation failed for componen ...
最新文章
- Codeforces 895C - Square Subsets
- 【学术相关】新一轮“双一流”名单公布!这些学校上榜
- 下列叙述正确的是( )
- android动态化ui框架,动态化高性能的 UI 框架 Virtualview-Android
- [JavaWeb-JavaScript]JavaScript流程控制语句
- layui复选框:被js操作checked切换并显示状态(含案例、代码)
- python 近期用到的基础知识汇总(五)
- 用 Zabbix 监控值统计每个月触发器告警次数
- NO.170 六问禅道1:为什么任务的剩余工时不自动更新?
- codeblock异常关闭,重新开机,启动时提示有另外的实例在运行的解决办法。
- javaweb JAVA JSP学生考勤管理系统考勤管理系统jsp学生迟到早退考勤查询系统(考勤管理系统源码)
- 遥感计算机解释技术PPT,梅安新 遥感导论.ppt
- 程序员的忠告:为什么避免使用 SELECT * 查询,效率低?
- java mp3合并_java合并MP3文件
- vulnhub靶机-Pwned
- 三年级计算机 键盘指法 教案,三年级下册信息技术教案-第06课键盘指法练习浙江摄影版(新)...
- 电子科技大学计算机科学与技术考研复试,电子科技大学计算机科学与工程学院2021考研招生复试工作安排...
- 吉林大学计算机研究生成绩计算方法,关于同济大学研究生成绩计算方法的说明...
- 8.22 ps课堂练习
- 个人永久性免费-Excel催化剂功能第98波-零代码零距离轻松接触并拥有金融大数据...
热门文章
- What is Type in managed heap?
- python这个软件学会能做什么工作-不要再复制粘贴了 !学会Python,分分钟搞定一整天的工作...
- python现在第几版-2020 年10月编程语言排行榜,Python 排名逼近第二
- python开发安卓程序-如何使用python开发Android手机应用?
- python编程在哪里写-python入门该从哪里开始?
- python使用教程pandas-Python 数据处理库 pandas 入门教程基本操作
- 学python多长时间能够精通-Python培训需要多长时间可以学会?
- python3.6手册中文版-python3.6中文手册下载|
- python下什么版本-python版本有什么不同
- 用python画皮卡丘代码-实现童年宝可梦,教你用Python画一只属于自己的皮卡丘