DRF Viewset 删除详细路线的权限

DRF Viewset remove permission for detail route

我有一个基本的视图集:

class UsersViewSet(viewsets.ModelViewSet):
    permission_classes = (OnlyStaff,)
    queryset = User.objects.all()
    serializer_class = UserSerializer

它绑定到 /api/users/ 端点。我想创建一个用户个人资料页面,所以我只需要一个特定的用户,所以我可以从 /api/users/<id>/ 检索它,但问题是我希望 /api/users/<id>/ 允许任何人使用,但是 /api/users/ 保留其权限 OnlyStaff,因此任何人都无法访问完整的用户列表。

注意:也许这不是一个很好的实现,因为任何人都可以暴力破解增加 id 的数据,但我愿意将其从 <id> 更改为 <slug> .

如何删除详细路线的权限?

提前致谢。

如果您发布了许可 class。

会有所帮助

但是从您发布的内容来看,似乎只有员工用户才能访问绑定到该视图集的端点。这意味着没有其他用户 type/role 可以访问这些端点。

关于你的问题,你似乎想设置一个 IsOwnerOrStaffOrReadOnly 权限并覆盖 ModelViewSet 的列表路由功能并替换 permission_classes 然后调用 super

class UsersViewSet(viewsets.ModelViewSet):
    permission_classes = (IsOwnerOrStaffOrReadOnly,)
    queryset = User.objects.all()
    serializer_class = UserSerializer

def list(self, request, *arg, **kwargs):
   self.permission_classes = (OnlyStaffCanReadList,)
   super(UsersViewSet, self).list(request, *args, **kwargs)  // python3 super().list(request, *args, **kwargs)

是 Owner 对象权限 class

class IsOwnerOrStaffOrReadOnly(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        if request.user.role == 'staff': 
           return True
        # Instance must have an attribute named `owner`.
        return obj.owner == request.user

只有工作人员可以读取权限class

class OnlyStaffCanReadList(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        if request.user.role == 'Staff': 
           return True
        else:
           return False

如评论中所述,您的用户模型必须具有所有者角色。如果你使用的是 django 用户模型,你可以做一个 obj.id == request.user.id 比较

重写 get_permissions() 方法如下

<b>from rest_framework.permissions import AllowAny</b>


class UsersViewSet(viewsets.ModelViewSet):
    permission_classes = (OnlyStaff,)
    queryset = User.objects.all()
    serializer_class = UserSerializer

    <b>def get_permissions(self):
        if self.action == 'retrieve':
            return [AllowAny(), ]        
        return super(UsersViewSet, self).get_permissions()</b>