Reputation: 1847
I'm building a student registration system by using django where students are registered. Students can be viewed only by their class teachers and school principals based on object level permission. There are School
, Class
and Student
models. Each school can have more than one school principals and each class can have more than one class teachers.
There will be two object level permissions:
I have searched through various 3rd party django libraries to implement such a hierarchical user group architecture. I have seen django-groups-manager, but it is a bit complicated for my issue. Then, I decided on django-mptt's registration of existing models feature and come up with model implementations such as:
from django.contrib.auth.models import Group
from django.db import models
import mptt
from mptt.fields import TreeForeignKey
TreeForeignKey(Group, on_delete=models.CASCADE, blank=True,
null=True).contribute_to_class(Group, 'parent')
mptt.register(Group, order_insertion_by=['name'])
class School(models.Model):
"""School object"""
name = models.CharField(max_length=255)
group = models.ForeignKey(
Group, related_name='school', on_delete=models.CASCADE)
class Class(models.Model):
"""Class object"""
name = models.CharField(max_length=255)
group = models.ForeignKey(
Group, related_name='class', on_delete=models.CASCADE)
school = models.ForeignKey(
School,
on_delete=models.CASCADE
)
class Student(models.Model):
"""Person object"""
fullname = models.CharField(max_length=255)
class = models.ForeignKey(
Class,
on_delete=models.CASCADE
)
In this way, each School
and Class
objects will have their own Group
s, school group being parent of the classes' groups of that particular school. So I can now create school principal users by using django's User
and assign it to the related parent group. By the same way, I can also create teacher users and assign them to their children groups of their class objects. And when a school principal or class teachers want to view their registered students, I can apply object level permission by filtering to their user groups.
My question is, is it the right way to do it? Is creating one group per each school/class objects meaningful?
Upvotes: 1
Views: 1989
Reputation: 1847
Thanks to nigel222's suggestion, instead of using built-in django groups, I have overriden built-in django User
model. I have also followed this tutorial which was really helpful. My latest version of models.py
is as follows (Don't forget to override default User
class, you need to let django know about it by adding AUTH_USER_MODEL = 'myapp.User'
to your settings.py
file):
from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
"""Custom user model with an extra type field"""
USER_TYPE_CHOICES = (
(1, 'superuser'),
(2, 'principaluser'),
(3, 'teacheruser'),
)
user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES)
class School(models.Model):
"""School object"""
name = models.CharField(max_length=255)
users = models.ManyToManyField(settings.AUTH_USER_MODEL)
class Class(models.Model):
"""Class object"""
name = models.CharField(max_length=255)
users = models.ManyToManyField(settings.AUTH_USER_MODEL)
school = models.ForeignKey(
School,
on_delete=models.CASCADE
)
class Student(models.Model):
"""Person object"""
fullname = models.CharField(max_length=255)
class = models.ForeignKey(
Class,
on_delete=models.CASCADE
)
Upvotes: 2