Tuesday 14 January 2020

Filter Django Admin user list according to logged in user

So I'm building a school management system in 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.

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.



from Filter Django Admin user list according to logged in user

1 comment: