如何应用节流只是为了在DRF视图集中创建动作?



我有一个视图集,我想只对该视图集的create动作应用节流,我不希望它应用于update,destroy,retrieve等…

class UserViewSet(viewsets.ModelViewSet):
# should only be applied to the create action
throttle_classes = [SomeThrottle] 
...

正如在Introspecting ViewSet actions [DRF docs]中所描述的那样,您可以检查action属性,通过覆盖get_throttles方法来根据当前操作设置throttle_classes:

class UserViewSet(viewsets.ModelViewSet):
def get_throttles(self):
if self.action == 'create':
throttle_classes = [SomeThrottle]
else:
throttle_classes = []  # No throttle for other actions
return [throttle() for throttle in throttle_classes]

如果使用ScopedRateThrottle代替自定义节流

# settings
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.ScopedRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'submit': '1/minute',
}

class SomeViewSet(mixins.CreateModelMixin, GenericViewSet)
....
def get_throttles(self):
if self.action == 'create':
self.throttle_scope = 'submit'
return super().get_throttles()

为了方便,我构建了一个Mixin。您可以在ViewSet上使用它,并将throttle_action_classes属性设置为throttle_classes的字典,其中键是操作,值是该操作的throttle_classes列表。

class ThrottlePerActionMixin(object):
"""
This mixing let you define throttles_classes per actions by passing a dict to throttle_action_classes attribute.
The throttle_classes on throttle_action_classes will be added to the default's ViewSet throttle_classes.
eg.:
class MyViewSet(ModelViewSet):
throttle_action_classes = {
'create': [CustomThrottleClass],
'retrieve': [AnonThrottleClass]
}
"""
def __init__(self, *args, **kwargs):
if not getattr(self, 'throttle_action_classes', None) or 
isinstance(self.throttle_action_classes, (list, tuple)):
raise Exception("Must set throttle_action_classes as a dict. "
"eg.: throttle_action_classes = {'create': [CustomThrottle]}")
super().__init__(*args, **kwargs)
def get_throttles(self):
throttles = super().get_throttles()
for action, throttle_classes_for_action in self.throttle_action_classes.items():
if self.action == action:
if not isinstance(throttle_classes_for_action, (list, tuple)):
throttle_classes_for_action = [throttle_classes_for_action]
for throttle_class in throttle_classes_for_action:
throttles.append(throttle_class())  # The throttles_class needs to be instantiated.
return throttles

相关内容

  • 没有找到相关文章

最新更新