Rest_Framework--throttling

访问频率组件
这个组件是用来控制单位时间内某个用户的访问次数的. 可以用在反爬虫中
基础的BaseThrottle类提供接口 接口函数为 allow_request,如果返回False则走wait
SimpleRateThrottle类给我们提供了get_cache_key接口,继承这个类要写rate(num_request, duration)多长时间内访问次数
实现原理如下代码:
class SimpleRateThrottle(BaseThrottle):
    def allow_request(self, request, view):
        if self.rate is None:
            return True

        self.key = self.get_cache_key(request, view)
        if self.key is None:
            return True

        self.history = self.cache.get(self.key, [])
        self.now = self.timer()

       # 原理的实现逻辑
        while 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()
 
题目:限制用户一分钟访问3次
代码逻辑
1.先建立一个访问记录字典,以用户ip作为键,以访问时间点作为值,作为列表 2.先判断当前时间,减去列表中的第一个时间, 1.如果时间大于60秒,说明不在一分钟之内,就把第一个值给删掉,然后把当前的时间添加到记录字典中去. 2.如果时间小于等于60秒,说明第一个值是在一分钟之内,然后再判断列表中的个数是否大于3, 如果大于等于3,则返回False,则表明频率超了,如果小于3则把当前的时间添加到记录字典中去,.返回True
mythrottle.py:
import time
from rest_framework.throttling import BaseThrottle

visit_record={}
class MyThrottles(BaseThrottle): #继承了这个类就不用自己定义wait了
    def allow_request(self,request,abc):#源码中规定必须有这个方法
        visit_ip=request.META.get("REMOTE_ADDR") #得到用户进来的IP地址 ,我们可也以用BaseThrottle这个类中的get_ident(request)来获得ip地址
        ctime=time.time()
        if visit_ip not in visit_record:
            visit_record[visit_ip]=[ctime]
            return True
        if len( visit_record[visit_ip])<3: #修改这里就可以修改登录次数
            visit_record[visit_ip].insert(0,ctime)
            return True
        if (ctime-visit_record[visit_ip][-1])>60:
            visit_record[visit_ip].insert(0, ctime)
            visit_record[visit_ip].pop()
            print(visit_record)
            return Trueviews.py
        return False
 
局部频率限制
views.py:
class BookViewSet(viewsets.ModelViewSet):
    # authentication_classes = [Authentication,]
    # permission_classes=[SvipPermissions]
    throttle_classes =[MyThrottles]
    queryset = Book.objects.all()
    serializer_class = Bookserializers
 
全局限制:
settings.py:
REST_FRAMEWORK={"DEFAULT_THROTTLE_CLASSES":["api_demo.service.mythrottle.MyThrottles"],
}
 
使用默认SimpleRateThrottle类
rest_framwork内置提供了几个频率限制类,基类就是BaseThrottle,
我们现在使用SimpleRateThrottle这个类来写频率限制组件
setting .py:
REST_FRAMEWORK = {
  "DEFAULT_THROTTLE_CLASSES": ["api_demo.service.mythrottle.MyThrottles"],
    "DEFAULT_THROTTLE_RATES": {
        "visit_rate": "5/m", #限制登录次数
    }
}
mythrottle.py:
import time
from rest_framework.throttling import BaseThrottle,SimpleRateThrottle

class MyThrottles(SimpleRateThrottle): #SimpleRateThrottle 这个类可以帮我们任意限定登录次数
    scope = "visit_rate"  #这里定义setting中的DEFAULT_THROTTLE_RATES对应的字典键值
    def get_cache_key(self, request, view):
        return self.get_ident(request)  #计算次数时以什么为键来记录登录时间,我们是以IP地址

 

posted @ 2020-12-13 16:48  盲仔不瞎忙  阅读(94)  评论(0编辑  收藏  举报