django-rest-framework:在ViewSet更新方法中添加其他权限

Ell*_*bal 4 python django django-rest-framework

我有以下代码:

class UsersViewSet(viewsets.ModelViewSet):
    model = Users
    permission_classes = (IsAuthenticated,)

    def update(self, request, *args, **kwargs):
        return super(UsersViewSet, self).update(request, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

问题是:

  • 如何仅为更新方法添加其他权限?(需要获得isAuthenticated + Permission)
  • 仅为更新方法覆盖权限?(只需要获得没有isAuthenticated的Permission)viewset中的其他方法应该具有IsAuthenticated权限

我可以用装饰器制作吗?还是其他什么?

想得到类似的东西:

@permission_classes((IsAuthenticated, AdditionalPermission ))
def update:
    pass
Run Code Online (Sandbox Code Playgroud)

但是,如果我编写此代码,则不会通过请求检查第二个权限

Ade*_*laN 16

稍后编辑

由于看起来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()
Run Code Online (Sandbox Code Playgroud)

这实际上适用于您提出的两种情况,但需要更多工作.但是,我已经测试了它并完成了这项工作.

下面的原始答案

文档中存在一个小错误,您应该向装饰器发送一个列表(而不是元组).所以它应该是这样的:

@permission_classes([IsAuthenticated, AdditionalPermission, ])
def update:
    pass
Run Code Online (Sandbox Code Playgroud)

回答你的问题:

如何仅为更新方法添加其他权限?

首先,您应该知道DRF首先检查全局权限(来自设置文件的权限),然后查看权限(在permission_classes中声明- 如果存在,它们将覆盖全局权限),并且仅在此之后检查方法权限(用装饰器@permission_classes声明.所以另一种方法是这样做:

@permission_classes([AdditionalPermission, ])
def update:
    pass
Run Code Online (Sandbox Code Playgroud)

由于已在整个视图上设置了ISAuthenticated,因此将始终在任何其他权限之前检查它.

仅为更新方法覆盖权限?

嗯,这很难(呃),但并非不可能.您可以:

  • 设置每个方法的权限并将其从类中删除
  • 修改您的AdditionalPermission类,以便在方法未更新时也检查用户身份验证.

祝好运.


小智 9

您还可以在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()
Run Code Online (Sandbox Code Playgroud)