简体   繁体   English

根据登录用户过滤Django Admin用户列表

[英]Filter Django Admin user list according to logged in user

So I'm building a school management system in Django Admin.所以我正在 Django Admin 中构建一个学校管理系统。 There are multiple institutions of that school and we want to build admins that can only manipulate data of students, teachers, etc. of that certain institute.那所学校有多个机构,我们想建立只能操纵该特定机构的学生、教师等数据的管理员。 Eg: if the admin user is of ABC institute, he/she should only able to edit data of ABC students, teachers, etc.例如:如果admin用户是ABC学院的,他/她应该只能编辑ABC学生、教师等的数据。

Here is my custom user and institute model:这是我的自定义用户和研究所模型:

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

Every institute has a domain principal:每个机构都有一个域负责人:

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'

I created the following custom admin to show only domain principals belonging to the institute the current admin user belongs to:我创建了以下自定义管理员以仅显示属于当前管理员用户所属机构的域主体:

@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
        )

But it's not working.但它不起作用。 It's still showing me the complete list.它仍在向我显示完整列表。

Solution 1: filter using institution name Without changing much of your code:解决方案 1:使用机构名称过滤而不更改您的大部分代码:

override get_queryset , something like, (not tested, please consider it as psuedo-code)覆盖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

Solution 2: DB separation方案二: DB分离

Keep separate DB per-institute and do DB routing为每个机构保留单独的数据库并进行 数据库路由

Solution 3: Group separation解决方案3:分组分离

Create groups-per-instituition and add users to groups during registration (user creation phase)创建每个机构的组并在注册期间将用户添加到组(用户创建阶段)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM