如何实现 Django 多用户类型,同时一个用户可以根据 he/she 正在进行的项目具有不同的角色?
How to implement Django multiple user types, while one user can have different role according to the project he/she is working on?
我找不到解决我的问题的方法,对此我将不胜感激 comments/help。
我想在 Django 中开发一个多用户类型模型,按照 this video where the author is using Django Proxy Models。
情况
我有 XX 个项目的列表(proj01
、proj02
、projXX
、...)。
所有这些项目都有其特定的页面,可以通过特定的 url mysite/projXX/
访问
我有多个用户:Adam、Bob、Caroline、Dany、Ed...
根据他们所从事的项目,每个用户都可以拥有多个角色(例如,经理、开发人员、记录员、审阅者、编辑……)
一个用户可以根据项目有不同的角色。例如。 Adam 可以是 proj01 的审稿人,但可以是 proj02 的编辑,而 Bob 可以是 proj01 的编辑,但可以是 proj02 的审稿人,等等。
我开始在下面的 models.py
文件中定义多个用户类型(仅限审阅者和编辑角色):
# accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
class User(AbstractUser):
class Types(models.TextChoices):
EDITOR= "EDITOR", "Editor"
REVIEWER = "REVIEWER", "Reviewer"
base_type = Types.EDITOR
type = models.CharField(
_("Type"), max_length=50, choices=Types.choices, default=base_type
)
name = models.CharField(_("Name of User"), blank=True, max_length=255)
def get_absolute_url(self):
return reverse("users:detail", kwargs={"username": self.username})
def save(self, *args, **kwargs):
if not self.id:
self.type = self.base_type
return super().save(*args, **kwargs)
class EditorManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(type=User.Types.EDITOR)
class ReviewerManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(type=User.Types.REVIEWER)
class EditorMore(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
gadgets = models.TextField()
class Editor(User):
base_type = User.Types.EDITOR
objects = EditorManager()
class Meta:
proxy = True
def edit(self):
return "Edition in progress"
class ReviewerMore(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
model = models.CharField(max_length=255)
make = models.CharField(max_length=255)
year = models.IntegerField()
class Reviewer(User):
base_type = User.Types.REVIEWER
objects = ReviewerManager()
@property
def more(self):
return self.reviewermore
class Meta:
proxy = True
def review(self):
return "In Review"
问题:
处理用户角色可以根据正在访问的项目页面 he/she 更改这一事实的最佳方法是什么?
示例:如果 Adam 已登录并访问页面 mysite/proj01/
,我希望他只访问审阅者允许的内容,而如果 Adam 访问 mysite/proj02/
,我希望用户仅查看编辑器允许的内容。
理想情况下,我希望每个用户在用户数据库中都有其唯一的条目。我在想项目相关的角色级别可以存储为字典吗?例如:
{'proj01':'reviewer', 'proj02':'editor', 'projxx': 'roleY', ... }
如何将此用户模型与项目相关权限列表结合起来?
编辑 21 年 2 月 7 日
为 project
应用添加示例文件,models.py
和 views.py
:
# projects/models.py
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
from django.urls import reverse
class Project(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("project_detail", args=[str(self.id)])
# projects/views.py
from django.contrib.auth.mixins import (
LoginRequiredMixin,
UserPassesTestMixin,
)
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
from django.urls import reverse_lazy
from .models import Project
class ProjectListView(LoginRequiredMixin, ListView):
model = Project
template_name = "project_list.html"
class ProjectDetailView(LoginRequiredMixin, DetailView):
model = Article
template_name = "project_detail.html"
class ProjectUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Project
fields = (
"title",
"body",
)
template_name = "project_edit.html"
def test_func(self):
obj = self.get_object()
return obj.author == self.request.user
如果您有项目作为模型。您可以向模型添加自定义权限。然后为每个项目适当地将这些权限分配给您的用户(实际上也很容易 add/remove 权限)。
然后在您的 views/template 中使用 user_passes_test
或 permissions_required
来限制用户可以 see/access/edit.
class Project(models.Model):
project_name = ...
class RoleType(models.Model):
role_name = models.CharField
# Permission boolean flags
can_edit = models.Boolean
can_view = models.Boolean
class ProjectRole(models.Model):
project = models.ForeignKey('Project', ...)
role = models.ForeignKey('RoleType', ...)
user = models.ForeignKey('User', ...)
现在您可以根据项目或用户进行反向查找
# To show all assigned users and their roles for a project
foo_project = Project.objects.get(project_name='foo')
project_roles = ProjectRole.objects.filter(project=foo_project)
您还可以通过角色及其权限布尔标志来限制您的视图和模板。
- 创建定义您的角色的组,例如:组 1:编辑,Group2:Manager 等等
- 将每个用户分配到指定的组(您可以在 python manage.py shell 或管理面板中完成)
- 添加视图限制,例如:/mysite/projx/视图被限制为groupA,您可以查看以下对您有帮助的问题:
例如:
GroupA : GlobalEditor ( Bob 可以在 projx 和 projy 编辑,只能查看 projz )
GroupB : viewonly (Adam 只能查看项目的内容)
等等
我找不到解决我的问题的方法,对此我将不胜感激 comments/help。
我想在 Django 中开发一个多用户类型模型,按照 this video where the author is using Django Proxy Models。
情况
我有 XX 个项目的列表(proj01
、proj02
、projXX
、...)。
所有这些项目都有其特定的页面,可以通过特定的 url mysite/projXX/
我有多个用户:Adam、Bob、Caroline、Dany、Ed...
根据他们所从事的项目,每个用户都可以拥有多个角色(例如,经理、开发人员、记录员、审阅者、编辑……)
一个用户可以根据项目有不同的角色。例如。 Adam 可以是 proj01 的审稿人,但可以是 proj02 的编辑,而 Bob 可以是 proj01 的编辑,但可以是 proj02 的审稿人,等等。
我开始在下面的 models.py
文件中定义多个用户类型(仅限审阅者和编辑角色):
# accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
class User(AbstractUser):
class Types(models.TextChoices):
EDITOR= "EDITOR", "Editor"
REVIEWER = "REVIEWER", "Reviewer"
base_type = Types.EDITOR
type = models.CharField(
_("Type"), max_length=50, choices=Types.choices, default=base_type
)
name = models.CharField(_("Name of User"), blank=True, max_length=255)
def get_absolute_url(self):
return reverse("users:detail", kwargs={"username": self.username})
def save(self, *args, **kwargs):
if not self.id:
self.type = self.base_type
return super().save(*args, **kwargs)
class EditorManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(type=User.Types.EDITOR)
class ReviewerManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(type=User.Types.REVIEWER)
class EditorMore(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
gadgets = models.TextField()
class Editor(User):
base_type = User.Types.EDITOR
objects = EditorManager()
class Meta:
proxy = True
def edit(self):
return "Edition in progress"
class ReviewerMore(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
model = models.CharField(max_length=255)
make = models.CharField(max_length=255)
year = models.IntegerField()
class Reviewer(User):
base_type = User.Types.REVIEWER
objects = ReviewerManager()
@property
def more(self):
return self.reviewermore
class Meta:
proxy = True
def review(self):
return "In Review"
问题:
处理用户角色可以根据正在访问的项目页面 he/she 更改这一事实的最佳方法是什么?
示例:如果 Adam 已登录并访问页面 mysite/proj01/
,我希望他只访问审阅者允许的内容,而如果 Adam 访问 mysite/proj02/
,我希望用户仅查看编辑器允许的内容。
理想情况下,我希望每个用户在用户数据库中都有其唯一的条目。我在想项目相关的角色级别可以存储为字典吗?例如:
{'proj01':'reviewer', 'proj02':'editor', 'projxx': 'roleY', ... }
如何将此用户模型与项目相关权限列表结合起来?
编辑 21 年 2 月 7 日
为 project
应用添加示例文件,models.py
和 views.py
:
# projects/models.py
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
from django.urls import reverse
class Project(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("project_detail", args=[str(self.id)])
# projects/views.py
from django.contrib.auth.mixins import (
LoginRequiredMixin,
UserPassesTestMixin,
)
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
from django.urls import reverse_lazy
from .models import Project
class ProjectListView(LoginRequiredMixin, ListView):
model = Project
template_name = "project_list.html"
class ProjectDetailView(LoginRequiredMixin, DetailView):
model = Article
template_name = "project_detail.html"
class ProjectUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Project
fields = (
"title",
"body",
)
template_name = "project_edit.html"
def test_func(self):
obj = self.get_object()
return obj.author == self.request.user
如果您有项目作为模型。您可以向模型添加自定义权限。然后为每个项目适当地将这些权限分配给您的用户(实际上也很容易 add/remove 权限)。
然后在您的 views/template 中使用 user_passes_test
或 permissions_required
来限制用户可以 see/access/edit.
class Project(models.Model):
project_name = ...
class RoleType(models.Model):
role_name = models.CharField
# Permission boolean flags
can_edit = models.Boolean
can_view = models.Boolean
class ProjectRole(models.Model):
project = models.ForeignKey('Project', ...)
role = models.ForeignKey('RoleType', ...)
user = models.ForeignKey('User', ...)
现在您可以根据项目或用户进行反向查找
# To show all assigned users and their roles for a project
foo_project = Project.objects.get(project_name='foo')
project_roles = ProjectRole.objects.filter(project=foo_project)
您还可以通过角色及其权限布尔标志来限制您的视图和模板。
- 创建定义您的角色的组,例如:组 1:编辑,Group2:Manager 等等
- 将每个用户分配到指定的组(您可以在 python manage.py shell 或管理面板中完成)
- 添加视图限制,例如:/mysite/projx/视图被限制为groupA,您可以查看以下对您有帮助的问题:
例如: GroupA : GlobalEditor ( Bob 可以在 projx 和 projy 编辑,只能查看 projz )
GroupB : viewonly (Adam 只能查看项目的内容) 等等