我想基于10秒,10分钟和1天的持续时间设置视图的速率限制。因此,假设用户每天可以发送20个请求/ 10秒,100个请求/ 10分钟和1000个请求。
我尝试进行限制,但找不到设置多个请求的任何方法。 我已经尝试过django-ratelimit软件包,但是我也找不到任何这样的选项,因为它为rate设置了单个字符串,例如rate ='5 / 10m'。 请让我知道是否有解决此问题的方法
答案 0 :(得分:0)
documentation on django-ratelimit
中对此进行了介绍。您可以在同一视图上定义多个@ratelimit
装饰器。
此外,费率格式还允许您添加number to the denominator:
您还可以指定多个单位,即:
X/Yu
,其中Y
是多个单位。如果省略u
,则假定为秒。因此,以下内容是等效的,均表示“每五分钟一百个请求”:100/5m 100/300s 100/300
因此,您可以将这些限制定义为:
from ratelimit.decorators import ratelimit
@ratelimit(key='user', rate='20/10s')
@ratelimit(key='user', rate='100/10m')
@ratelimit(key='user', rate='1000/d')
def some_view(request):
pass
对于基于类的视图(例如ViewSet
),您可以使用@method_decorator
装饰它,例如:
django.utils.decorators import method_decorator
from ratelimit.decorators import ratelimit
@method_decorator(ratelimit(key='user', rate='20/10s'), name='dispatch')
@method_decorator(ratelimit(key='user', rate='100/10m'), name='dispatch')
@method_decorator(ratelimit(key='user', rate='1000/d'), name='dispatch')
class MyViewSet(ViewSet):
# ...
答案 1 :(得分:0)
因为我在下面使用,所以不适用于通用视图。
@method_decorator(ratelimit(key='user', rate='1000/d'), name='dispatch')
class MyViewSet(ViewSet):
我找到了另一个解决方案。
from django.http import JsonResponse
from ratelimit.decorators import ratelimit
class RateLimitForSecurity(View):
@ratelimit(key='ip', rate='30/m')
def dispatch(self, request, *args, **kwargs):
was_limited = getattr(request, 'limited', False)
if was_limited:
return JsonResponse({"code": 1, 'msg': 'try many times'},json_dumps_params={'ensure_ascii':False})
return super().dispatch(request, *args, **kwargs)
class IndexView(RateLimitForSecurity, generic.ListView):
# same as before
答案 2 :(得分:0)
我正在研究这个,发现你可以覆盖油门类函数 parse_rate 并且它可以根据你的需要进行自定义
from rest_framework.throttling import UserRateThrottle
class ThirdPartyMonthlyThrottle(UserRateThrottle):
scope = 'third_party_monthly'
def parse_rate(self, rate):
if rate is None:
return None, None
num, period = rate.split('/')
num_requests = int(num)
duration = int(period)*86400
return num_requests, duration
'DEFAULT_THROTTLE_RATES': {
'third_party_monthly': '3/30'
}
这可以解释为每月 3 个请求