I'm writing a rest API with the Django REST framework, and I'd like to protect certain endpoints with permissions. The permission classes look like they provide an elegant way to accomplish this. My problem is that I'd like to use different permission classes for different overridden ViewSet methods.
我正在用Django REST框架编写一个rest API,我想用权限保护某些端点。权限类看起来像是提供了一种优雅的方法来实现这一目标。我的问题是我想为不同的重写ViewSet方法使用不同的权限类。
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
def create(self, request, *args, **kwargs):
return super(UserViewSet, self).create(request, *args, **kwargs)
@decorators.permission_classes(permissions.IsAdminUser)
def list(self, request, *args, **kwargs):
return super(UserViewSet, self).list(request, *args, **kwargs)
In the code above I'd like to allow registration (user creation) for unauthenticated users too, but I don't want to let list users to anyone, just for staff.
在上面的代码中,我也想允许未经身份验证的用户注册(用户创建),但我不想让列表用户只为工作人员。
In the docs I saw examples for protecting API views (not ViewSet methods) with the permission_classes
decorator, and I saw setting a permission classes for the whole ViewSet. But it seems not working on overridden ViewSet methods. Is there any way to only use them for certain endpoints?
在文档中,我看到了使用permission_classes装饰器保护API视图(而不是ViewSet方法)的示例,我看到为整个ViewSet设置了一个权限类。但它似乎不适用于重写的ViewSet方法。有没有办法只将它们用于某些端点?
14
I think there is no inbuilt solution for that. But you can achieve this by overriding the get_permissions
method:
我认为没有内置的解决方案。但是你可以通过覆盖get_permissions方法来实现这一点:
from rest_framework.permissions import AllowAny, IsAdminUser
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes_by_action = {'create': [AllowAny],
'list': [IsAdminUser]}
def create(self, request, *args, **kwargs):
return super(UserViewSet, self).create(request, *args, **kwargs)
def list(self, request, *args, **kwargs):
return super(UserViewSet, self).list(request, *args, **kwargs)
def get_permissions(self):
try:
# return permission_classes depending on `action`
return [permission() for permission in self.permission_classes_by_action[self.action]]
except KeyError:
# action is not set return default permission_classes
return [permission() for permission in self.permission_classes]
1
I created a superclass that is derived from @ilse2005's answer. In all subsequent django views you can inherit this to achieve action level permission control.
我创建了一个派生自@ ilse2005答案的超类。在所有后续的django视图中,您可以继承此视图以实现操作级别权限控制。
class MixedPermissionModelViewSet(viewsets.ModelViewSet):
'''
Mixed permission base model allowing for action level
permission control. Subclasses may define their permissions
by creating a 'permission_classes_by_action' variable.
Example:
permission_classes_by_action = {'list': [AllowAny],
'create': [IsAdminUser]}
'''
permission_classes_by_action = {}
def get_permissions(self):
try:
# return permission_classes depending on `action`
return [permission() for permission in self.permission_classes_by_action[self.action]]
except KeyError:
# action is not set return default permission_classes
return [permission() for permission in self.permission_classes]
本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2016/03/13/6f4fd856803e54a1d0f7f823af83b17c.html。