Reputation: 1761
i have two api view (django rest framework):
class ApiView1(APIView):
...
throttle_classes = (UserRateThrottle, )
and api 2:
class ApiView2(APIView):
...
throttle_classes = (UserRateThrottle, )
and my settings:
REST_FRAMEWORK = {
...,
'DEFAULT_THROTTLE_RATES': {
'user': '5/minute'
}
}
when request the ApiView1 for five time, every thing is okay, but after that when request the ApiView2, i get a http 429 status code with:
Request was throttled. Expected available in 45 seconds.
Question: can i use throttling per user and per view? if yes, How it can be done?
Upvotes: 3
Views: 4254
Reputation: 1704
Yes, you can.
For class-based views:
class YourView(APIView):
throttle_classes = (UserRateThrottle, )
def get(self, request, format=None):
content = { ... Your response here ... }
return Response(content)
For function-based views you can use the decorator: @throttle_classes([UserRateThrottle])
_Reference: https://www.django-rest-framework.org/api-guide/throttling/
Upvotes: 1
Reputation: 6276
Because it's the feature of django-rest-framework.
The ScopedRateThrottle class can be used to restrict access to specific parts of the API. This throttle will only be applied if the view that is being accessed includes a .throttle_scope property. The unique throttle key will then be formed by concatenating the "scope" of the request with the unique user id or IP address.
The allowed request rate is determined by the DEFAULT_THROTTLE_RATES setting using a key from the request "scope".
Since you don't set the throttle_scope the any view, both ApiView1
and ApiView2
use the same throttle scope scope
. So they share the same limit. If one view is over-accessed, another view will be unacceptable either.
In your scenario, you should set different throttle_scope in the apiview and add the scope to REST_FRAMEWORK.DEFAULT_THROTTLE_RATES
.
If you have many throttle scope and don't want to add too many scopes in settings.py
, you should create your own Throttle
class and override the get_cache_key
function.
class MyThrottle(UserRateThrottle):
def get_cache_key(self, request, view):
return "throttle_{viewid}_{indent}".format(
viewid=id(view),
indent=self.get_indent(request)
)
This ThrottleClass can automatic set different scope for different view.
Upvotes: 3