day85
频率校验
源码分析
声明:基于rest_framework的频率校验
1.首先我们进入到APIView下的dispatch,因为由此方法开始分发的
2.可以看到dispatch方法下有一个initial的方法,进入该方法
3.由此进入频率控制
4.进入check_throttles方法,我们发现他最终是调用了该方法,所以我们需要在自定义时,写上这个方法
5.同时我们进入上张图中的迭代对象,发现与认证组件和权限控制一样他也需要在视图类中写一个列表
6.最后我们想他若是频率控制住后需要返回信息来到BaseThrottle,发现可以重写wait返回一个数字。
代码实现
自定义频率控制
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle import time class MyThrottle(BaseThrottle): dic = {'ip': []} def __init__(self): now_time = 0 history = [] def allow_request(self, request, view): self.now_time = time.time() ip = request.META.get("REMOTE_ADDR") if ip not in self.dic: self.dic[ip] = [self.now_time, ] return True self.history = self.dic.get(ip) while self.history and self.now_time - self.history[-1] > 60: self.history.pop() if len(self.history) < 3: self.history.insert(0, self.now_time) return True return False def wait(self): return 60 - (self.now_time - self.history[-1])
视图函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.shortcuts import render, HttpResponse from rest_framework.views import APIView from app01 import the from rest_framework import exceptions class User(APIView): throttle_classes = [the.MyThrottle, ] def get(self, request): return HttpResponse('get') def post(self, request): return HttpResponse('post')
使用rest_framework自带的频率控制
settting中设置
REST_FRAMEWORK = { 'DEFAULT_THROTTLE_RATES': { 'ttt': '3/m' } }
在试图类中写一个继承Throttled的类可以控制返回信息为中文
def throttled(self, request, wait): class Mythrottled(exceptions.Throttled): default_detail = '访问次数过多' extra_detail_singular = '剩余 {wait} 秒后访问.' extra_detail_plural = '剩余 {wait} 秒后访问.' raise Mythrottled(wait)
在py文件中设置相关值
class MyThrottle(SimpleRateThrottle): scope = 'ttt' def get_cache_key(self, request, view): # self.get_ident( request) return request.META.get('REMOTE_ADDR')
局部控制
局部使用: -在视图类中写 throttle_classes = [MyThrottle,]
全局控制
全局使用: -在setting中写 'DEFAULT_THROTTLE_CLASSES':['app01.MyAuth.MyThrottle',], -局部禁用: -在视图类中写 throttle_classes = []