首页 > 解决方案 > 根据登录用户过滤 Django Admin 用户列表

问题描述

所以我在 Django Admin 中构建了一个学校管理系统。那所学校有多个机构,我们希望建立只能操作该机构的学生、教师等数据的管理员。例如:如果管理员用户是 ABC 学院,他/她应该只能编辑 ABC 学生、教师等的数据。

这是我的自定义用户和机构模型:

class Institute(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name


class User(AbstractUser):
    """
    Our own User model. Made by overriding Django's own AbstractUser model.
    We need to define this as the main user model in settings.py with 
    variable AUTH_USER_MODEL *IMPORTANT* 
    """
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField(
        max_length=255,
        unique=True,
        verbose_name="email address"
    )
    institute = models.ForeignKey(
        Institute, on_delete=models.SET_NULL, null=True)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email

每个研究所都有一个领域负责人:

class DomainPrincipal(User):
    is_admin = True

    def __str__(self):
        return self.first_name+" "+self.last_name

    # Control model features
    class Meta:
        verbose_name = 'Domain Principal'
        verbose_name_plural = 'Domain Principals'

我创建了以下自定义管理员以仅显示属于当前管理员用户所属机构的域主体:

@admin.register(UserPrincipal)
class DomainPrincipalAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'institute')

    def queryset(self, request):
        qs = super(DomainPrincipalAdmin, self).queryset(request)
        return qs.filter(
            institute=request.user.institute
        )

但它不起作用。它仍在向我显示完整的列表。

标签: pythondjango

解决方案


解决方案 1: 使用机构名称过滤而不更改大部分代码:

覆盖get_queryset 之类的(未经测试,请将其视为伪代码)

class DomainPrincipalAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.user:
            current_instituition_name = user.instituition_name
            qs = qs.filter(institute = current_instituition_name)
        return qs

解决方案 2:数据库分离

为每个研究所保留单独的数据库并进行数据库路由

解决方案 3:分组分离

为每个机构创建组并在注册期间将用户添加到组(用户创建阶段)


推荐阅读