Django DRF-限制通过权限访问列表视图

时间:2018-07-16 23:16:40

标签: python django python-3.x permissions django-rest-framework

我有一个DRF ViewSet,我要向其中添加CanViewAndEditStaff权限。我只希望某些用户(user.access_level < 2)能够查看工作人员列表。在我的Permissions类中,如何区分对list视图和get项目视图的调用。这是我的权限类别:

class CanViewAndEditStaff(permissions.BasePermission):

        def has_permission(self, request, view):

            # IF THIS IS A LIST VIEW, CHECK ACCESS LEVEL
            if ( request.user.access_level < 3 ):
                return True

            # ELSE, CONTINUE ON TO OBJECT PERMISSIONS

        def has_object_permission(self,request,view,account):

            # admin can do anything
            if ( request.user.access_level == 1 ):
                return True

            # view/edit/delete
            else:

                # users can view their own account
                if  account == request.user:
                    return True

                elif account.access_level >= request.user.access_level:
                    return True

            return False

2 个答案:

答案 0 :(得分:4)

class CanViewAndEditStaff(permissions.BasePermission):

    def has_permission(self, request, view):

        # IF THIS IS A LIST VIEW, CHECK ACCESS LEVEL
        if (view.action == 'list' and request.user.access_level < 3 ):
            return True

        # ELSE, CONTINUE ON TO OBJECT PERMISSIONS

您可以使用view.action来了解这是列表还是其他内容。

答案 1 :(得分:0)

这不能完全准确地解决问题,但是该技术适用。

我在Ykh的答案上使用了一个变体,该变体允许在显示各种不同模型的许多视图中广泛使用同一权限类。

在视图类中,我添加了一个属性以区分原始视图,从而允许进行适当的对象比较以确定权限

# views.py
class SomeView(ListAPIView):
    permission_classes = (IsPermd, )
    is_some_view = True

class SomeOtherView(RetrieveAPIView
    permission_classes = (IsPermd, )
    is_some_other_view = True

# permissions.py
class IsPermd(BasePermission):
    def has_object_permissions(self, request, view, obj):
        if hasattr(view, 'is_some_view'):
            # whatever special considerations
        if hasattr(view, 'is_some_other_view'):
            # whatever other special considerations

这感觉有些笨拙,但是直到我找到更好的方法为止,我都会坚持下去。