rest_framework 访问频率(节流)流程

访问频率流程

访问频率流程与认证流程非常相似,只是后续操作稍有不同

当用发出请求时 首先执行dispatch函数,当执行当第二部时:

   #2.处理版本信息 处理认证信息 处理权限信息 对用户的访问频率进行限制
            self.initial(request, *args, **kwargs)

进入到initial方法:

  def initial(self, request, *args, **kwargs):
        """
        Runs anything that needs to occur prior to calling the method handler.
        """
        self.format_kwarg = self.get_format_suffix(**kwargs)

        # Perform content negotiation and store the accepted info on the request
        neg = self.perform_content_negotiation(request)
        request.accepted_renderer, request.accepted_media_type = neg

        # Determine the API version, if versioning is in use.
        #2.1处理版本信息
        version, scheme = self.determine_version(request, *args, **kwargs)
        request.version, request.versioning_scheme = version, scheme

        # Ensure that the incoming request is permitted
        #2.2处理认证信息
        self.perform_authentication(request)
        #2.3处理权限信息
        self.check_permissions(request)
        #2.4对用户的访问频率进行限制
        self.check_throttles(request)
 #2.4对用户的访问频率进行限制
        self.check_throttles(request)

下面 开始 限流的具体分析:

一、执行check_throttles方法

    def check_throttles(self, request):
        """
        Check if request should be throttled.
        Raises an appropriate exception if the request is throttled.
        """
        #遍历throttle对象列表
        for throttle in self.get_throttles():
            #根据allow_request()的返回值进行下一步操作,返回True的话不执行下面代码,标识不限流,返回False的话执行下面代码,还可以抛出异常
            if not throttle.allow_request(request, self):
                #返回False的话执行
                self.throttled(request, throttle.wait())

局部访问频率

throttles.py

#局部访问频率
from rest_framework.throttling import BaseThrottle
import time
class VisitThorttles(object):
    visit_thorttles={}
    def __init__(self):
        self.history=None

    def allow_request(self,request,view):
        current_time=time.time()
        # 访问用户的IP
        visit_ip=request.META.get("REMOTE_ADDR")
        # 第1 次访问时
        if visit_ip not in self.visit_thorttles:
            self.visit_thorttles[visit_ip]=[current_time]

            return True
        self.history = self.visit_thorttles[visit_ip]

        # 第2、3次访问   默认单位时间只能访问3次,
        if len(self.visit_thorttles[visit_ip])<3:
            # 最新访问时间放在列表第一个
            self.visit_thorttles[visit_ip].insert(0,current_time)
            return True

        # # 判断当前时间与用户最早访问时间(列表对三个时间)的差值
        if current_time-self.visit_thorttles[visit_ip][-1]>60:
                self.visit_thorttles[visit_ip].pop()
                self.visit_thorttles[visit_ip].insert(0,current_time)
                return True

        return False

view.py

class BookViewsSet(viewsets.ModelViewSet): 

    # 访问频率
    throttle_classes=[VisitThorttles]

    queryset = Book.objects.all()
    serializer_class = BookModelSerializer

全局访问频率

throttles.py

#局部访问频率
from rest_framework.throttling import BaseThrottle
import time
class VisitThorttles(object):
    visit_thorttles={}
    def __init__(self):
        self.history=None

    def allow_request(self,request,view):
        current_time=time.time()
        # 访问用户的IP
        visit_ip=request.META.get("REMOTE_ADDR")
        # 第1 次访问时
        if visit_ip not in self.visit_thorttles:
            self.visit_thorttles[visit_ip]=[current_time]

            return True
        self.history = self.visit_thorttles[visit_ip]

        # 第2、3次访问   默认单位时间只能访问3次,
        if len(self.visit_thorttles[visit_ip])<3:
            # 最新访问时间放在列表第一个
            self.visit_thorttles[visit_ip].insert(0,current_time)
            return True

        # # 判断当前时间与用户最早访问时间(列表对三个时间)的差值
        if current_time-self.visit_thorttles[visit_ip][-1]>60:
                self.visit_thorttles[visit_ip].pop()
                self.visit_thorttles[visit_ip].insert(0,current_time)
                return True

        return False

settings.py

REST_FRAMEWORK={
    "DEFAULT_THROTTLE_CLASSES":["api.servise.throttles.VisitThorttles"],
}

内置访问频率

htorttles.py

# 内置的htorttles:
from rest_framework.throttling import SimpleRateThrottle

class VisitThorttles(SimpleRateThrottle):
    # 范围 visit_rate可自定义,与settings相匹配
    scope = "visit_rate"
    def get_cache_key(self, request, view):

        return self.get_ident(request)

settings.py

REST_FRAMEWORK = {

    "DEFAULT_THROTTLE_RATES":{
       'tiga':'10/m',
       'anno':'5/m',
       'user':'10/m',
       'admin':'20/m',
    }
}

待续

原文地址:https://www.cnblogs.com/caochao-/p/8809809.html