• 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',
        }
    }

    待续

  • 相关阅读:
    web端常见兼容性问题整理
    浏览器初始化样式
    html5特效库
    csshack
    进程与线程,并发、并行、异步、多线程
    js复制粘贴事件
    dom range相关
    vue和react在使用上的对比
    ListView往TreView里面拖拽
    ListView添加项目带序列
  • 原文地址:https://www.cnblogs.com/caochao-/p/8809809.html
Copyright © 2020-2023  润新知