如何将自定义值从 DRF ModelViewSet 传递到权限 class?

How can custom values be passed from a DRF ModelViewSet to a permissions class?

我已经设置了一个 custom permissions class 可以从多个视图中重复使用,在一个应用程序中,一些用户代表其他用户拥有类似所有权的权利:

class IsOwnerLike(permissions.BasePermission):
    def has_permission(self, request, view):
        if (
            user_is_owner(request.user, request.data["owned_by"])
            | user_is_owner_like(request.user, request.data["owned_by"])
        ):
            return True

        return False

对于一个 ModelViewSet,这按预期工作。

但是,由于遗留原因,进入不同视图的不同请求可能没有 "owned_by" 数据元素 -- 它可能被称为 "owned"、"owner"、"created_by", 等等——因此我不能像写的那样重用这个自定义权限。

在视图集中抽象事物、规范化传递给我的自定义权限的数据的正确方法是什么 class?可以这样做吗,还是我应该考虑以不同方式处理这些权限?

您应该使用 from has_object_permission 进行对象检查以获取模型访问权限,如下所示:

    def has_object_permission(self, request, view, obj):
        if hasattr(obj, 'owner'):
           if obj.user == request.user:
              return True
        return False

您可以使用您的模型所有者字段名称更改所有者

为了将 owner kwargs 传递给权限 class,您应该编写 custommmModelViewSet 并从 ModelViewSet 继承并覆盖 get_permissions() 方法

找到解决方案。

我能够向视图添加自定义属性:

class ViewOne(ModelViewSet):
    ownership_fieldname = "owned_by"
    permission_classes = [IsOwnerLike]

    ...

class ViewTwo(ModelViewSet):
    ownership_fieldname = "owner"
    permission_classes = [IsOwnerLike]
    ...

然后在权限中访问:

class IsOwnerLike(permissions.BasePermission):
    def has_permission(self, request, view):
        if (
            user_is_owner(request.user, request.data[view.ownership_fieldname])
            | user_is_owner_like(request.user, request.data[view.ownership_fieldname])
        ):
            return True

        return False