Django-restframework 之频率源码分析
Django-restframework 之频率源码分析
一 前言
经过权限判断之后就是进行频率的判断了,而频率的判断和权限又不一样,认证、权限和频率的执行流程都差不多,使用配置里面的相关类来进行判断。而不和认证和权限一样,频率的配置没有,查看APIView的类属性如下:


二 频率组件执行流程
虽然restframework原生灭有配置频率,但是提供了几个进行频率判断的类,如下:

其中SimpleRateThrottle类是根据访问者 ip 来进行频率限制的一个类,来看看这个类的执行流程。
1. init方法

2. get_rate

3. 执行 allow_request方法

4. get_cache_key

5. 时间差判断

6. throttle_success

认证失败的话执行throttle_failure,其实就是返回False。
7. wait

三 自定义频率组件
1. 自定义频率类
频率类需要继承自带的频率类
# from rest_framework.throttling import BaseThrottle
class BookThrottle(BaseThrottle):
    VISIT_RECORD = {}
    def __init__(self):
        self.history = None
    def allow_request(self, request, view):
        print(request.META)
        REMOTE_ADDR = request.META.get('REMOTE_ADDR')
        import time
        ctime = time.time()
        if REMOTE_ADDR not in self.VISIT_RECORD:
            self.VISIT_RECORD[REMOTE_ADDR] = [ctime,]
            return True
        self.history = self.VISIT_RECORD.get(REMOTE_ADDR)
        while self.history and ctime - self.history[-1] > 60:
            self.history.pop()
        if len(self.history) < 3:
            self.history.insert(0, ctime)
            return True
        else:
            return False
    def wait(self):
        import time
        ctime = time.time()
        return 60 - (ctime - self.history[-1])
# 频率类代码注释
         # 访问频率的逻辑
#         #     {'ip地址':[16:13:39,16:13:19,],'ip地址2':[时间1,时间2],}
#         # (1)取出访问者ip
#         # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
#         # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
#         # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
#         # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
#         #(1)取出访问者ip
#         # print(request.META)
#         # REMOTE_ADDR 就是访问者的ip:127.0.0.1
#         ip=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,]
#             # {'127.0.0.1':[时间1,时间1,]}
#             return True
#         # self.history=[时间1,时间1,]
#         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 True
#         else:
#             return False
2. 使用
使用很简单,在需要进行频率控制的视图类中定义一个属性throttle_classes,如下:
class Book(APIView):
    authentication_classes = [authticate_classes.BookAuth]
    permission_classes = [permiss_classes.LoginPermission]
    throttle_classes = [thrott_classes.BookThrottle]
    # authentication_classes = []
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)
    def get(self, request, id):
        print(request.user, '444')
        response = {'status': 100, 'msg': None}
        book_obj = models.Book.objects.filter(pk=id).first()
        if book_obj:
            book_ser = myser.BookSer(book_obj, many=False)
            response['book'] = book_ser.data
        else:
            response['msg'] = '图书没有对象'
            response['status'] = 101
        return Response(response)
四 配置自定义频率类
1. 局部配置
其实上面的就是局部配置,
class Book(APIView):
    authentication_classes = [authticate_classes.BookAuth]
    permission_classes = [permiss_classes.LoginPermission]
    throttle_classes = [thrott_classes.BookThrottle]
2. 全局使用
全局配置如下:
REST_FRAMEWORK={
    'DEFAULT_THROTTLE_CLASSES': ['app01.thrott_classes.BookThrottle']
}
3. 局部禁用
局部禁用需要在视图类中定义一个空的throttle_classes属性
throttle_classes = []
												
											Django-restframework 之频率源码分析的更多相关文章
- Django搭建及源码分析(三)---+uWSGI+nginx
		
每个框架或者应用都是为了解决某些问题才出现旦生的,没有一个事物是可以解决所有问题的.如果觉得某个框架或者应用使用很不方便,那么很有可能就是你没有将其使用到正确的地方,没有按开发者的设计初衷来使用它,当 ...
 - Django如何启动源码分析
		
Django如何启动源码分析 启动 我们启动Django是通过python manage.py runsever的命令 解决 这句话就是执行manage.py文件,并在命令行发送一个runsever字 ...
 - Django之DRF源码分析(二)---数据校验部分
		
Django之DRF源码分析(二)---数据校验部分 is_valid() 源码 def is_valid(self, raise_exception=False): assert not hasat ...
 - Django rest framework 源码分析 (1)----认证
		
一.基础 django 2.0官方文档 https://docs.djangoproject.com/en/2.0/ 安装 pip3 install djangorestframework 假如我们想 ...
 - Django rest framework源码分析(3)----节流
		
目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...
 - Django rest framework源码分析(1)----认证
		
目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...
 - django CBV视图源码分析
		
典型FBV视图例子 url路由系统 from django.conf.urls import url from django.contrib import admin from luffycity.v ...
 - Django rest framework源码分析(一)  认证
		
一.基础 最近正好有机会去写一些可视化的东西,就想着前后端分离,想使用django rest framework写一些,顺便复习一下django rest framework的知识,只是顺便哦,好吧. ...
 - Django中间件部分源码分析
		
中间件源码分析 中间件简介 中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定的 ...
 
随机推荐
- NOIP2017 酱油送命记
			
Day0 一天,在机房,有点考前的紧张和慌张,打了一下午的模板,立了3个不该立的flag... Day1 拿到试题,万分紧张,T1是数论啊 害怕,一直以为D2T1才是数论,仔细观察却发现(flag1: ...
 - 映射内网ftp服务器到公网后内网访问出错问题
			
上文说道映射后外网无法访问解决:https://www.cnblogs.com/Dev0ps/p/9073048.html 添加了ftp的pasv_address的地址 ,内网客户端要设置主动模式(a ...
 - 在Eclipse上Maven环境配置使用
			
1. 安装配置Maven: 1.1 从Apache网站 http://maven.apache.org/ 下载并且解压缩安装Apache Maven. Maven下载地址: http://maven. ...
 - 【填坑纪事】一次用System.nanoTime()填坑System.currentTimeMills()的实例记录
			
JDK提供了两个方法,System.currentTimeMillis()和System.nanoTime(),这两个方法都可以用来获取表征当前时间的数值.但是如果不仔细辨别这两个方法的差别和联系,在 ...
 - python接口自动化(十八)--重定向(Location)(详解)
			
简介 在实际工作中,有些接口请求完以后会重定向到别的url,而你却需要重定向前的url.URL主要是针对虚拟空间而言,因为不是自己独立管理的服务器,所以无法正常进行常规的操作.但是自己又不希望通过主域 ...
 - Javascript的内存泄漏分析
			
作为程序员(更高大尚的称谓:研软件研发)的我们,无论是用Javascript,还是.net, java语言,肯定都遇到过内存泄漏的问题.只不过他们都有GC机制来帮助程序员完成内存回收的事情,如果你是C ...
 - Python爬虫入门教程 63-100 Python字体反爬之一,没办法,这个必须写,反爬第3篇
			
背景交代 在反爬圈子的一个大类,涉及的网站其实蛮多的,目前比较常被爬虫coder欺负的网站,猫眼影视,汽车之家,大众点评,58同城,天眼查......还是蛮多的,技术高手千千万,总有五花八门的反爬技术 ...
 - java到底是引用传递还是值传递?
			
今天我们来讲讲一个在学习中容易误解的问题,面试中也偶尔问到,java方法调用时到底是值传递还是引用传递? 首先,请大家来做一个判断题,下面的3个问题是否描述正确 1. java基本数据类型传递是值传递 ...
 - java_stream流
			
Stream流的个人理解 整体来看,流式思想类似于工厂车间的“生产流水线”,通过一些列操作来获取我们需要的产品 在Java 8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream概念 ...
 - 深入浅出—Redis集群的相关详解
			
前言: 这篇文章主要介绍了Redis集群的相关,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值. 注意!要求使用的都是redis3.0以上的版本,因为3.0以上增加了red ...