【问题标题】:How to define multiple throttle in django rest framework如何在 django rest 框架中定义多个油门
【发布时间】:2020-11-30 01:06:01
【问题描述】:

django_Rest_framework 的文档说明:

如果您想同时施加突发限制率和持续限制率,也可以使用多个限制。例如,您可能希望将用户限制为每分钟最多 60 个请求,每天最多 1000 个请求

但是,并没有说明如何实现这样的情况。

我尝试过类似的方法,但没有成功

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day',
        'user': ['30/minute', '1000/day']
    }
}

【问题讨论】:

  • 这应该可以。是什么让你认为它没有?
  • 我已经尝试过了,它引发了异常:'list' object has no attribute 'split'。我正在使用该应用程序的非最新版本:djangorestframework==3.6.4。我无法更改站点在 django 1.8 中运行。

标签: django-rest-framework


【解决方案1】:

可以,但需要定义多个限制,每个时间单位一个。

  1. 首先,您在设置中定义您需要的所有限制,例如每分钟不超过 30 个,每天不超过 1000 个。
        REST_FRAMEWORK = {
          'DEFAULT_THROTTLE_CLASSES': (
                    'rest_framework.throttling.AnonRateThrottle',
              'rest_framework.throttling.UserRateThrottle'
          ),
          'DEFAULT_THROTTLE_RATES': {
              'anon': '100/day',
              'user_min': '30/minute',
              'user_day': '1000/day',
          }
        }
  1. 您将 Throttling 类添加为具有您定义的范围的 UserRateThrottle 的子类:
from rest_framework.throttling import UserRateThrottle

class UserMinThrottle(UserRateThrottle):
             scope = 'user_min'
  1. 最后在您设置为 throttle_class 的 APIView 上,使用您在上一步中定义的限制的类。
class YourAPIView(APIView):
     throttle_classes = [
          UserMinThrottle,
          UserDayThrottle
     ]

【讨论】:

    【解决方案2】:

    这是一个很好的问题,我遇到了一个更复杂的情况,因为我只想对我的 ViewSet 的一个方法应用多个限制(在我的例子中是创建/POST)。

    所以首先我想出了如何仅为 ViewSets 中的特定方法应用节流阀,然后我发现了这篇文章:http://www.pedaldrivenprogramming.com/2017/05/throttling-django-rest-framwork-viewsets/

    由于ViewSet继承了APIView,所以我做到了,所以我将追加APIViewthrottle_classes列表

    import myprojectname.throttles as throttles # throttles.py
    
    class MyFooViewSet(viewsets.ViewSet):
    
    
    # Only throttle specific methods
    def get_throttles(self):
        if self.action in ['create']:
            # Apply these throttle classes 
            self.throttle_classes.append(throttles.FooThrottleBurst)
            self.throttle_classes.append(throttles.FooThrottleSustained)
            # ...
    

    throttles.py 看起来像这样(没什么特别的,就像https://www.django-rest-framework.org/api-guide/throttling/#userratethrottle

    from rest_framework.throttling import UserRateThrottle
    
    class FooThrottleBurst(UserRateThrottle):
        scope = 'mynamespace.burst'
    
    class FooThrottleSustained(UserRateThrottle):
        scope = 'pricereport.sustained'
    

    这些费率当然是在 settings.py 中定义的:

    # ... some example values
    'mynamespace.burst':        '3/minute',
    'mynamespace.sustained':    '5/hour',
    # ...
    

    在使用 Postman 进行测试后,我能够在一分钟内完成 3 次成功的 POST(4 次明显受到限制)。在等待约 60 秒并提出新请求后,应用了“持续”限制规则(5/小时),DRF 向我返回:

    {
        "detail": "Request was throttled. Expected available in 3538 seconds."
    }
    

    我不知道OP的情况,但我想分享我的方法

    【讨论】:

      【解决方案3】:

      您不能拥有UserRateThrottle 的费率列表。

      根据documentation,您必须配置一个范围以允许多个速率。

      在你的情况下,它将是:

      class BurstRateThrottle(UserRateThrottle):
          scope = 'burst'
      
      class SustainedRateThrottle(UserRateThrottle):
          scope = 'sustained'
      
      REST_FRAMEWORK = {
          'DEFAULT_THROTTLE_CLASSES': (
              'rest_framework.throttling.AnonRateThrottle',
              'example.throttles.BurstRateThrottle',
              'example.throttles.SustainedRateThrottle'
          ),
          'DEFAULT_THROTTLE_RATES': {
              'anon': '100/day',
              'burst': '60/min',
              'sustained': '1000/day'
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-08-15
        • 2016-05-03
        • 2021-09-15
        • 2018-08-18
        • 2021-09-19
        • 2013-06-21
        • 2016-05-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多