简体   繁体   中英

Django - What is the best approach to handle multiple user types…and route the HTML pages based on this?

I'm making a small test project with below user types: School Admin, Teacher, Student, Parent. And each user type will have different Permissions like School Admin has full access... Parents can only view their Childern's Activity. Teacher can see all students but can add / edit marks for their respective students only. Teachers can setup Exam etc.. Students can take exam and submit the exam, but cannot edit / add any other information. Just can edit his profile detail.

Approach 1: Do i need to create a Custom User calss and apply to each user type (ie one Custome Class.. and 4 user type calss).. and similarly have 4 different view and html pages?

Approach 2: Just have one custome class and have an field with UserType which will have the have as "SchoolAdmin", "Teacher", "Student","Parent".. and one view and html (as the data page would remain same and only data record will restrict), and somehow identify the User Type in View, and filter the record?

Definately some view or html pages will be specific to one user type only which is i am able to handle, the issue is to use same view / html page to handle all user type.

Please suggest... and any code snippet will will more helpful.

# models.py
---------------------
class CustomUser(AbstractUser):
    USER_TYPE_CHOICES = (
        ('SchoolAdmin'),
        ('Teacher'),
        ('Student'),
        ('Parents'),
    )

    user_type = models.CharField(blank=False, choices=USER_TYPE_CHOICES)
    name = models.CharField(blank=False, max_length=255)
    country = models.CharField(blank=False, max_length=255)
    city = models.CharField(blank=False, max_length=255)
    phone = models.CharField(blank=True, max_length=255)
    created_at = models.DateField(auto_now_add=True)

    def __str__(self):
        return self.name


class SchoolAdmin(models.Model):
    user = models.OneToOneField(
        CustomUser, on_delete=models.CASCADE, primary_key=True)


class Teacher(models.Model):
    user = models.OneToOneField(
        CustomUser, on_delete=models.CASCADE, primary_key=True)
    photo = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)


class Student(models.Model):
    user = models.OneToOneField(
        CustomUser, on_delete=models.CASCADE, primary_key=True)
    teacher = models.ForeignKey(Teacher)
    photo = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)

class Parent(models.Model):
    user = models.OneToOneField(
        CustomUser, on_delete=models.CASCADE, primary_key=True)
    student= models.ForeignKey(Student)

Your CustomUser class is essentially correct. You don't really need the other classes (SchoolAdmin, Teacher, Student, Parent) as that functionality is described by user_type .

You do need to change the user type choices, something like:

SCHOOL, TEACHER, STUDENT, PARENT = 'school', 'teacher', 'student', 'parent'
USER_TYPES: (
    (SCHOOL, 'School'),
    (TEACHER, 'Teacher'),
    (STUDENT, 'Student'),
    (PARENT, 'Parent'),
)

The photo field can be added to the CustomUser class.

Furthermore, you will want to familiarize yourself with Django's documentation on custom authentication and permissions and authorization .

You can then create groups and permissions and assign your users to those. Teachers are a group with specific permissions, etc.

Also you can differentiate by user_type in your templates and views, to show or hide information, or access. For example:

def exam_setup_view(request):
    # only teachers allowed here, others see 404
    if request.user.user_type != CustomUser.TEACHER:
        raise Http404()

EDIT This article explains how to use Django's groups and permissions. For example, you can create custom permissions on your User's Meta class, like so:

class CustomUser(AbstractUser):
    # ...
    class Meta:
        permissions = (
            ("can_create_exam", "Can create exam"),
            ("can_view_user", "Can view user"),
        )

That will create those custom permissions. You can assign those to users in Django's Admin, or programmatically, as further explained in that article or Django's documentation.

There are several ways of testing if a user has those permissions, ie: use the permission_required decorator, or when you have a user instance in your view: user.has_perm('appname.can_create_exam') , or from a template: {% if perms.appname.can_create_exam %} .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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