我有以下代码:
class UsersViewSet(viewsets.ModelViewSet):
model = Users
permission_classes = (IsAuthenticated,)
def update(self, request, *args, **kwargs):
return super(UsersViewSet, self).update(request, *args, **kwargs)
问题是:
我可以使用装饰器制作吗?还是其他什么?
想得到类似的东西:
@permission_classes((IsAuthenticated, AdditionalPermission ))
def update:
pass
但是,如果我编写此代码,则不会通过请求检查第二个权限
答案 0 :(得分:13)
稍后编辑
由于看起来DRF装饰员不能真正起作用(至少不适合我),这是我能想到的最好的解决方案:
def get_permissions(self):
# Your logic should be all here
if self.request.method == 'GET':
self.permission_classes = [DummyPermission, ]
else:
self.permission_classes = [IsAuthenticated, ]
return super(UsersViewSet, self).get_permissions()
这实际上适用于您提出的两种情况,但需要更多工作。但是,我已经对它进行了测试,并完成了这项任务。
以下的原始答案
文档中存在一个小错误,您应该向装饰器(而不是元组)发送一个列表。所以它应该是这样的:
@permission_classes([IsAuthenticated, AdditionalPermission, ])
def update:
pass
回答你的问题:
如何仅为更新方法添加其他权限?
首先,您应该知道DRF首先检查全局权限(来自设置文件的权限),然后查看权限(在 permission_classes 中声明 - 如果存在,它们将覆盖全局权限)并且仅在此之后获得方法权限(使用装饰器 @permission_classes 声明)。所以另外一种方法就是这样:
@permission_classes([AdditionalPermission, ])
def update:
pass
由于已经在整个视图中设置了 ISAuthenticated ,因此将始终在任何其他权限之前对其进行检查。
仅为更新方法覆盖权限?
嗯,这很难(呃),但并非不可能。你可以:
答案 1 :(得分:7)
您还可以在 get_permissions()方法中指定特定方法的权限:
class MyViewSet(viewsets.ModelViewSet):
def get_permissions(self):
if self.action in ('update', 'other_viewset_method'):
self.permission_classes = [permissions.CustomPermissions,]
return super(self.__class__, self).get_permissions()
答案 2 :(得分:2)
@permission_classes不适用于基于类的视图。我尝试了@detail_route(permission_classes =(permissions.CustomPermissions,))来获取更新视图功能,但仍无效。
所以,我的解决方案是:
class MyViewSet(viewsets.ModelViewSet):
def update(self, request, *args, **kwargs):
self.methods=('put',)
self.permission_classes = (permissions.CustomPermissions,)
return super(self.__class__, self).update(request, *args, **kwargs)
试一试。我的drf是v3.1.1
答案 3 :(得分:0)
是的,您可以添加注释 有关更多信息,请参阅此链接:
答案 4 :(得分:0)
对我来说,get_permissions起作用了,但是事实证明,即使将权限设置为AllowAny,如果在请求rest框架的标头中发送Authorization,也会抛出错误。如果您要同时使用授权和AllowAny,则必须考虑到这一点。