来自 BasePermission 的 Django (drf) 动态权限

Django (drf) dynamic permissions from BasePermission

我想有一个简单的方法来检查某人是否是 postproposal 等的所有者或管理员,他正在尝试编辑\删除。

所以,每次我使用 IsAuthenticated 权限并在 ModelViewSet 的方法中,我都会获取实例并检查 instance.author 或有时 instance.owner 是否是请求的用户它(request.user == instance.owner 在某些对象上它是 request.user == instance.author)。

问题

主要问题是:如何创建权限 class 以在实例上使用动态用户属性名称检查这种所有权?

我的一个解决方案(我认为不是最好的)

我创建了函数,该函数采用用户属性实例名称 returns 权限 class:

def is_owner_or_admin_permission_factory(owner_prop_name):
    class IsOwnerOrAdmin(BasePermission):
        def has_permission(self, request, view, *args, **kwargs):
            instance = view.get_object()
            try:
                owner = getattr(instance, owner_prop_name)
            except AttributeError:
                return False
            return (
                request.user and request.user.id and (owner == request.user or request.user.is_staff)
            )

    return IsOwnerOrAdmin

几天来我也对同样的确切问题感到沮丧,并且在处理具有不同查找名称的多个模型时,我设法找到了合适的解决方法(当然至少对我而言)用户属性。

解决方法是这样的,在 ModelViewSet 视图中定义了一个单独的属性 user_lookup_kwarg,可用于检查适当的权限。

例如,

class YourViewSet(viewsets.ModelViewSet):
    queryset = YourModel.objects.all()
    serializer_class = YourSerializer
    user_lookup_kwarg = 'user' #or 'account/created_by' whatever.

现在,您的 permission_class 会有点像这样,

class CustomPermission(BasePermission):

    def has_object_permission(self, request, view, obj):
        try:
            return request.user.is_superuser or getattr(obj, view.user_lookup_kwarg) == request.user
        except:
            return False
        return request.user.is_superuser

您只需要覆盖 has_object_permission() 方法来检查实例级别的权限。