在 Django admin 中,如何管理复杂的用户权限?

In Django admin, how do I manage complex user privileges?

提问人:Mundi 提问时间:11/2/2023 更新时间:11/4/2023 访问量:46

问:

假设你在 Django 中有这个具有多对多关系的实体结构:

- Company
  - Division
    - Department
      - Unit

每个用户都是 的一部分,因此我通过为具有 或权限的用户分配来管理在 Django Admin 中创建、编辑和删除实体的权限。例如“DepartmentAdmin”、“DivisionAdmin”等。为了确定正确的权限,我只是跟踪了链条。很简单。UnitDepartmentDivisionCompanyUnit

现在我必须重构:用户现在可以是多个的成员(也许保留他们的“主要”)。他们可以拥有任意的权利来管理任何其他,等等。UnitUnitDepartmentDivision

我该如何最好地建模?

我尝试过使用一个新实体,一种带有有关角色/权限的附加信息的联接表。这是个好主意吗?我发现这在其他地方产生了很多依赖关系,并且确定权限非常复杂。Membership

例如

class Membership(models.Model):
    user = models.ForeignKey(User,
       on_delete=models.CASCADE, related_name="other_departments")
    department = models.ForeignKey(Department, 
       on_delete=models.CASCADE, related_name="other_members")
    position = models.CharField(_("Position"), max_length=32, null=True, blank=True)

或者有没有更好的方法利用 Django 现有的管理员权限管理功能?你会怎么做?

谢谢!

python django 数据结构 django-admin

评论

0赞 nigel239 11/2/2023
Django 的多表继承在这里可能有很大的帮助,你只需要翻转你的例子;使该部门继承自单位;部门划分等...这也将允许像您要求的那样的树形结构。只是抛出一个想法。:)
0赞 Mundi 11/3/2023
@nigel239 所以你的意思是每个部门等都直接维护其管理员、成员等的用户列表......右?这几乎就是我的成员资格表会做的事情。
0赞 SamSparx 11/3/2023
像 Django-Guardian 这样的东西在这里可能有用,尤其是在权限级联的情况下

答:

1赞 Awais khan 11/4/2023 #1

若要对用户可以是多个单位的成员并具有管理不同部门、分部和公司的任意权限的方案进行建模,可以将多对多关系与其他权限和角色的中间模型一起使用。这是解决它的一种方法:

  • 保留标准的 Django 用户模型进行用户身份验证。
  • 按照原来的方式定义单元模型。
  • 创建一个模型,该模型表示用户在不同单元中的成员身份及其在这些单元中的角色/特权。此模型将包含用于存储有关用户角色、部门、部门和公司的信息的字段。
from django.db import models

class Membership(models.Model):
     user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="memberships")
     unit = models.ForeignKey(Unit, on_delete=models.CASCADE, related_name="memberships")
     position = models.CharField(_("Position"), max_length=32, null=True, blank=True)

权限模型: 您可以创建一个模型来定义用户在一个单元中可以拥有的不同权限和角色(例如,管理员、经理等)。此模型可用于授予和管理特定权限。

class Permission(models.Model):
    name = models.CharField(max_length=50)
    description = models.TextField()

class MembershipRole(models.Model):
    membership = models.ForeignKey(Membership, on_delete=models.CASCADE)
    permission = models.ForeignKey(Permission, on_delete=models.CASCADE)

使用此结构,您可以:

  1. 将用户与多个设备关联,每个设备都有其特定的角色和权限。 在权限模型中定义不同的权限/角色(例如,DepartmentAdmin、DivisionAdmin 等)。
  2. 通过在 MembershipRole 模型中创建记录,将用户与这些权限相关联。
  3. 根据用户在单位中的成员身份和角色检查用户的权限。

在视图或控制器中,可以通过查询用户的成员身份和角色来确定用户的权限。你还可以将 Django 的内置权限系统与此模型结合使用,以进一步控制对特定操作和视图的访问。

此方法应使你能够灵活地处理用户是多个单元的成员,并在每个单元中拥有任意权限,同时还可以更轻松地管理和查询用户权限。

评论

0赞 Mundi 11/14/2023
这与我的想法相符。角色的抽象是一个很好的建议,我也会采纳。谢谢。