Suppose you have this entity structure in Django with to-many relationships:
- Company
- Division
- Department
- Unit
Every user is part of a Unit
, so I managed the rights to create, edit and delete entities in Django Admin by assigning groups for users that had Department
, Division
or Company
privileges. E.g. "DepartmentAdmin", "DivisionAdmin", etc. To determine the correct privilege, I just followed the Unit
up the chain. Easy enough.
Now I have to refactor: users can now be members of more than one Unit
(perhaps keeping their "main" Unit
). They can have arbitrary rights to administer any other Department
, Division
, etc..
How would I best model that?
I have tried with a new entity Membership
, a kind of join table with additional information about the role / privileges. Is this a good idea? I found that this creates a lot of dependencies elsewhere and determining the rights is quite complicated.
e.g.
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)
Or is there a better way by leveraging the existing admin rights management features of Django? How would you go about this?
Thanks!
To model the scenario where users can be members of more than one Unit and have arbitrary rights to administer different Departments, Divisions, and Companies, you can use a many-to-many relationship with an additional intermediate model for privileges and roles. Here's one way to approach it:
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)
Permissions Model: You can create a model to define different permissions and roles (e.g., Admin, Manager, etc.) that users can have within a unit. This model can be used to grant and manage specific privileges.
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)
With this structure, you can:
In your views or controllers, you can determine a user's rights by querying their memberships and roles. You can also use Django's built-in permissions system in combination with this model to further control access to specific actions and views.
This approach should provide you with the flexibility to handle users being members of multiple units and having arbitrary rights within each unit, while also making it easier to manage and query user privileges.