【问题标题】:How can custom values be passed from a DRF ModelViewSet to a permissions class?如何将自定义值从 DRF ModelViewSet 传递到权限类?
【发布时间】:2026-01-06 17:00:01
【问题描述】:

我设置了一个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”等——因此我无法按书面规定重复使用此自定义权限。

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

【问题讨论】:

  • 如果你使用 created_by 那么它不会工作,你必须创建不同的权限类

标签: python django django-rest-framework permissions django-rest-viewsets


【解决方案1】:

您应该使用 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

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

为了将所有者 kwargs 传递给权限类,您应该编写 custommModelViewSet 并从 ModelViewSet 继承并覆盖 get_permissions() 方法

【讨论】:

  • 感谢您的回复!在这种情况下,我正在处理一个 POST 请求,因此该对象还不存在。此权限测试旨在确定用户创建对象的权限。
  • 这样您就可以在执行创建时调用 check_permission
【解决方案2】:

找到了解决办法。

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

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

【讨论】:

    最近更新 更多