简体   繁体   English

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

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

I've set up a custom permissions class to be reused from multiple views, in an app where some users have ownership-like rights on behalf of other users:我已经设置了一个自定义权限 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

This works as expected for one ModelViewSet.对于一个 ModelViewSet,这可以按预期工作。

However, for legacy reasons, different requests coming in to different views may not have an "owned_by" data element -- it may be called "owned", "owner", "created_by", etc. -- and therefore I can't reuse this custom permission as written.但是,由于遗留原因,进入不同视图的不同请求可能没有“owned_by”数据元素——它可能被称为“owned”、“owner”、“created_by”等——因此我不能重用此自定义权限。

What is the correct way to abstract things at the viewset, to normalize data being passed to my custom permissions class?在视图集中抽象事物、规范传递给我的自定义权限 class 的数据的正确方法是什么? Can this be done, or should I be thinking about handling these permissions differently?可以这样做,还是我应该考虑以不同的方式处理这些权限?

Found a solution.找到了解决办法。

I was able to add a custom attribute to the view:我能够向视图添加自定义属性:

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

    ...

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

And then access it in the permission:然后在权限中访问它:

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

you should use from has_object_permission for object check for model access permission like this:您应该从 has_object_permission 使用 object 检查 model 访问权限,如下所示:

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

you can change owner with your models owner field name您可以使用模型所有者字段名称更改所有者

and for pass owner kwargs to permission class you should write custommModelViewSet and inheritance from ModelViewSet and override get_permissions() method对于将所有者 kwargs 传递给权限 class 您应该从 ModelViewSet 编写 custommModelViewSet 和 inheritance 并覆盖 get_permissions() 方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM