【问题标题】:How to Handle 3 level permisions on fields in Django REST framework如何处理 Django REST 框架中字段的 3 级权限
【发布时间】:2015-01-28 11:43:03
【问题描述】:

我正在构建 Django REST 作为后端,Angular JS 作为前端。

现在我的权限系统非常先进,达到 3 级

class UserSerializer(serializers.Serializer):
    email = serializers.EmailField()
    username = serializers.CharField(max_length=100)
    field1 = serializers.CharField(max_length=100)
    field2 = serializers.CharField(max_length=100)
    field3 = serializers.CharField(max_length=100)
    field4 = serializers.CharField(max_length=100)

现在需要权限

User Role
view
READ / Write / Update /Delete

有10个角色,30个view赞/user/view1/user/view2然后读或写like

这些是字段级别的权限,例如

Field1 can be READ by Manager level on view 1
Field1 can be Edit by Manager level on view 2
Feild1 can be Delete by Admin on View 1

我很困惑我怎么能拥有那种权限模型。

【问题讨论】:

  • 您希望如何设置这些权限?我已经大致了解了如何做到这一点,但我不知道您希望如何定义权限。
  • 您是否找到了满足您要求的解决方案?我处于类似的位置,正在寻找一种理智的方法来解决问题

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


【解决方案1】:

我通常会针对这些情况推荐不同的序列化程序类,但这会限制您的读写权限(某种程度),并且可能无法完全满足您的需求。

您将为每个权限级别创建一个序列化程序。假设有三个权限级别:管理员、经理、普通用户。

class NormalUserSerializer(ModelSerializer):
    email = serializers.EmailField(read_only=True, required=True)
    username = serializers.CharField(max_length=100, read_only=True)

    class Meta:
        fields = ("email", "username", )

class ManagerUserSerializer(NormalUserSerializer):
    email = serializers.EmailField(read_only=False, required=True)
    username = serializers.CharField(max_length=100, read_only=False)

class AdminSerializer(ManagerUserSerializer):
    email = serializers.EmailField(read_only=False, required=False)
    username = serializers.CharField(max_length=100, read_only=False)

这会将普通用户限制为字段的只读视图(read_only 由 DRF 强制执行)。对于管理人员来说,他们可以对字段进行读写,但他们无法清除email 字段的内容(由required 强制执行)。管理员可以读取和写入所有字段,以及清除 email 字段的内容。

然后,您的视图将根据经过身份验证的用户的角色在 get_serializer_class 中返回正确的序列化程序类。

class UserViewSet(ModelViewSet):

    def get_serializer_class(self):
        if self.request.user.is_superuser:
            return AdminUserSerializer

        if self.request.user.is_staff:
            return ManagerUserSerializer

        return NormalUserSerializer

另一个选项是强制执行 validate 方法中的所有内容,并在序列化程序上手动删除 to_native 方法中的字段。如果您可以为每个角色创建一个序列化程序,那么这是在 Django REST Framework 中的各个字段上实现基于角色的权限的最简单且(可以说)最简洁的方式。

【讨论】:

  • 问题是如果我有 10 个角色和 30 个模型,那么我必须定义 300 个序列化器。
  • @KKJOJ 这个答案不能很好地扩展,但我觉得基于字段的权限在 any 情况下不能很好地扩展。如果我想到一种更好、更具可扩展性的方法来做到这一点,那么我将发布一个单独的答案。
【解决方案2】:

我的客户也有同样的问题。我创建了django-rest-framework-roles 来根据用户类型自动参数化给定的 DRF 方法(例如:get_queryset、get_serializer_class)。这样您就不必针对用户类型重复输入条件块。

我想扩展该库以处理您所描述的更复杂的权限问题。我也有同样的挑战,例如:通过 Role HTTP 动词参数化。

【讨论】:

    猜你喜欢
    • 2013-10-08
    • 2020-02-13
    • 1970-01-01
    • 2017-04-13
    • 2016-11-20
    • 2016-03-26
    • 2014-08-25
    • 2016-01-25
    • 1970-01-01
    相关资源
    最近更新 更多