在我的Django应用程序中有一个完整的登录和注册系统,它允许我注册用户,登录用户,注销用户,更改密码,重置密码,邀请用户。我有所有的基本功能。
我现在想为用户提供工作区,按照以下几点:
- 每个工作区将有一个工作区管理员。
- 工作区管理员只能添加/删除(注册/删除)用户到自己的工作区。
- 用户只能对已添加到的工作空间做出反应(登录)。
- 超级用户(主管理员)可以管理所有工作区、所有工作区管理员和所有用户。
我如何完成这个?你可以说这和Slack类似。我只需要一个指导方针/路线图,我会自己实现它。
我已经创建了一个Workspace
模型,如下所示:
class Workspace(models.Model):
name = models.CharField(max_length=254)
created_at = models.DateTimeField(auto_now_add=True)
def make_admin(self, user):
user.is_workspace_admin = True
user.save()
def remove_admin(self, user):
user.is_workspace_admin = False
user.save()
和我的User
模型有以下两个属性除了其他默认的Django字段:
class User(AbstractBaseUser, PermissionsMixin):
is_workspace_admin = models.BooleanField(default=True)
workspaces = models.ManyToManyField(Workspace)
这个方法正确吗?如果不是,请引导我正确的方式。顺便说一句,使用这种方法,我可以向任何用户添加/分配工作空间,但是我如何能够管理登录到他们自己的工作空间的用户,并仅对他们已分配的工作空间作出反应。还有工作空间管理员控制其工作空间的用户等?
我知道如何使用Groups。那么假设我创建了所有相关的权限(你能告诉我如何创建权限吗?)来添加工作空间用户,删除工作空间用户,使工作空间用户成为工作空间管理员,从工作空间管理员中删除工作空间管理员等,并创建不同的组,并在每个组中添加相关权限。假设我的组看起来像manage_workspace_a
管理(添加/删除)工作空间用户组,manage_workspace_admins
管理(添加/删除)工作空间管理员,以及Django为每个模型提供的默认权限。
所以,我将如何能够拥有的功能,当一个"User A"
有is_superuser=True
,使"User B"
的is_workspace_admin=True
,那么"User B"
应该自动获得所有的工作空间管理权限。像这样:
workspace_user = User.objects.get(email="some-email-address")
if request.user.is_superuser:
wordspace_user.permissions.add([Workspace Admin Permissions])
有人可以用一个小代码示例解释整个过程吗?这是一个很长的,包含多个部分的问题,但希望我能给你指明正确的方向
-
我建议在您的User模型上添加另一个多对多字段,用于处理管理员状态。目前,您将其设置为布尔标志—因此管理员可以管理所有
-
就我个人而言,我会逆转M2M状态,并将
users
和administrators
放在工作空间上,而不是放在用户模型上。在用户模型上没有问题,但我觉得检查用户是否在工作空间的允许用户/管理员中,而不是检查工作空间是否在用户的工作空间和管理工作空间列表中,这更有意义。 -
您将需要更改将管理员添加到工作区的代码,因为您不想使用布尔标志:
def make_admin(self, user): self.administrators.add(user)
-
至于如何管理工作区本身,您可以将ORM过滤器放在相关视图的最开头:
def workspace_view(request, workspace_id): workspace = get_object_or_404(Workspace, workspace_id) if request.user not in workspace.users: return redirect(...) ...the rest of your view
请记住,除非管理员在
users
组中,否则不允许管理员在中—您要么需要将他们添加到users
中,要么添加另一个条件来检查他们是否在administrators
中。 -
如果您想要在某种索引/主页中的所有工作区的概述,您只需使用m2m反向访问器,这取决于您的反向名称(或默认的
/relation/_set
):def workspaces(request): workspaces = request.user.workspaces.all()
你绝对可以利用Django的内置权限系统,我建议你参考文档,因为这是一个很长的主题:
https://docs.djangoproject.com/en/4.0/topics/auth/default/permissions-and-authorization