按用户角色和 id 过滤的 Django 自定义权限

Posted

技术标签:

【中文标题】按用户角色和 id 过滤的 Django 自定义权限【英文标题】:Djnago custom permissions filtered by user role and id 【发布时间】:2021-11-26 14:26:56 【问题描述】:

我正在使用 Django Permissions 并试图了解如何实现

我有一个扩展的用户模型,其中用户具有角色:

class UserCustomModel(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    ROLES = (
        ('ADMIN', 'ADMIN'),
        ('SUPERUSER', 'SUPERUSER'),
        ('CONTRIBUTOR', 'CONTRIBUTOR'),
        ('READER', 'READER'),
    )
    roles = models.CharField(max_length=50, choices=ROLES, null=True)
    deleted = models.IntegerField(default=1)
    last_change_date = models.DateTimeField(auto_now=True)

还有一个客户(公司)的模型:

class CustomClient(models.Model):
    client_id = models.AutoField(primary_key=True)
    client_name = models.TextField()
    client_description = models.TextField()
    deleted = models.IntegerField(default=1)
    last_change_date = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.client_name)

每个用户只能分配给一个客户端。在第三个模型中显示:

class ClientUser(models.Model):
    class Meta:
        unique_together = (('user', 'client', 'group'),)

    user = models.ForeignKey(User, on_delete=models.CASCADE, primary_key=True)
    client = models.ForeignKey(CustomClient, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE) 
    deleted = models.IntegerField(default=1)
    last_change_date = models.DateTimeField(auto_now=True)

我在 Django 中为每个角色创建了组:

管理员 超级用户 贡献者 读者

这个想法是按用户的角色将用户分配到组中。它工作正常,但我想对这些组设置自定义权限。例如,如果用户具有角色 SUPERUSER,那么他/她可以添加/更改/删除具有角色 CONTRIBUTOR 和 READER 的用户。或者,如果用户是管理员,他/她可以添加/更改/删除具有所有其他角色的用户。并且必须受用户客户端ID的限制。

我无法从哪里开始,是否可以根据自定义用户角色设置权限? 我发现我可以检查用户是否具有这样的角色:

class IsAdmin(BasePermission):
    def has_permission(self, request, view):
        return request.user.role == "ADMIN"

但是我不知道如何进行,我当然可以从请求中获取 client_id。但是我应该在模型还是视图中使用这个类 IsAdmin(BasePermission)?

【问题讨论】:

BasePermission 只能在视图中使用吗? 【参考方案1】:

你做这样的事情:

permissions.py

def _is_in_group(user, group_name):
    """
    Takes a user and a group name, and returns `True` if the user is in that group.
    """
    if user == group_name:
        return user
    else:
        return None


def _has_group_permission(user, required_groups):
    return any([_is_in_group(user, group_name) for group_name in required_groups])

class IsAdminUser(permissions.BasePermission):
    required_groups = ["ADMIN"]

    def has_permission(self, request, view):
        has_group_permission = _has_group_permission(
            request.user.usergroup, self.required_groups
        )
        return request.user and has_group_permission

    def has_object_permission(self, request, view, obj):
        has_group_permission = _has_group_permission(
            request.user.usergroup, self.required_groups
        )
        return request.user and has_group_permission

views.py

在您的views 中设置IsAdminUser 以设置该权限

【讨论】:

以上是关于按用户角色和 id 过滤的 Django 自定义权限的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 管理自定义列中获取请求参数?

在 Django admin 中,如何按组过滤用户?

如何仅基于用户角色 Drupal 自定义 drupal 过滤器

按 django admin 中的自定义列表显示字段进行列表过滤

在 Django admin 中按自定义日期范围过滤

按Javascript中的角色数组过滤用户对象的数组