rest-framework访问频率的限制

一、官网文档(官网叫限流)

二、所谓的限流好处

  • 1、防止用户频繁的访问
  • 2、有效的防止的爬虫及第三方的攻击

三、直接在视图类中书写

四、单独定义一个类使用throttle_classes=[]加载进来

  • 1、单独定义一个类

    VISIT_RECORD = {}
    
    class VistitThrottle(object):
        """
        定义一个类限制1分钟内只能访问3次
        """
    
        def allow_request(self, request, view):
            # 1.获取用户当前的ip地址
            remote_addr = request.META.get('REMOTE_ADDR')
            ctime = time.time()
            # 2.如果当前ip从来没有访问就直接通过,并记住当前的时间
            if remote_addr not in VISIT_RECORD:
                VISIT_RECORD[remote_addr] = [ctime, ]
                return True
            # 3. 获取之前访问的时间
            history = VISIT_RECORD.get(remote_addr)
            # 4. 如果之前访问的时间小于当前时间-60(表示是在60秒前访问),就删除最早访问时间
            while history and history[-1] < ctime - 60:
                history.pop()
            # 5. 小于3的时候就插入到历史记录中
            if len(history) < 3:
                history.insert(0, ctime)
                return True
            return False
    
        def wait(self):
            """
            定义要等待多久才能访问
            :return:
            """
            return 10
    
  • 2、在视图类中使用

    class OrderView(APIView):
        authentication_classes = []
        permission_classes = []
        throttle_classes = [VistitThrottle]
    
        def get(self, request, *args, **kwargs):
            print(request.user.username)
            print(request.auth)
            res = {'code': 1, 'message': '失败', 'data': None}
            try:
                res['data'] = {'name': '哈哈'}
            except Exception as e:
                print(e)
            return JsonResponse(res)
    

五、处理等待时间,用户刷新的时候可以看到等待时间

  • 1、代码

    VISIT_RECORD = {}
    
    class VistitThrottle(object):
        def __init__(self):
            self.hostory = None
        """
        定义一个类限制1分钟内只能访问3次
        """
    
        def allow_request(self, request, view):
            # 1.获取用户当前的ip地址
            remote_addr = request.META.get('REMOTE_ADDR')
            ctime = time.time()
            # 2.如果当前ip从来没有访问就直接通过,并记住当前的时间
            if remote_addr not in VISIT_RECORD:
                VISIT_RECORD[remote_addr] = [ctime, ]
                return True
            # 3. 获取之前访问的时间
            self.history = VISIT_RECORD.get(remote_addr)
            # 4. 如果之前访问的时间小于当前时间-60(表示是在60秒前访问),就删除最早访问时间
            while self.history and self.history[-1] < ctime - 60:
                self.history.pop()
            # 5. 小于3的时候就插入到历史记录中
            if len(self.history) < 3:
                self.history.insert(0, ctime)
                return True
            return False
    
        def wait(self):
            """
            定义要等待多久才能访问
            :return:
            """
            ctime = time.time()
            return 60 - (ctime - self.history[-1])
    

六、继承rest_framework中的类实现限流

  • 1、导包

    from rest_framework.throttling import BaseThrottle
    
  • 2、继承BaseThrottle

七、全局配置

  • 1、单独定义一个工具文件
  • 2、在setting.py中配置

    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.AnonRateThrottle',
            'rest_framework.throttling.UserRateThrottle'
        ),
        'DEFAULT_THROTTLE_RATES': {
            'anon': '100/day',
            'user': '1000/day'
        }
    }
    
  • 3、在视图类中的使用

    from rest_framework.response import Response
    from rest_framework.throttling import UserRateThrottle
    from rest_framework.views import APIView
    
    class ExampleView(APIView):
        throttle_classes = (UserRateThrottle,)
    
        def get(self, request, format=None):
            content = {
                'status': 'request was permitted'
            }
            return Response(content)
    

results matching ""

    No results matching ""