python django 中的基本组层次结构

Basic group hierarchy in python django

我正在使用 django 建立一个学生注册系统,用于注册学生。根据对象级别权限,只有 class 教师和学校校长才能查看学生。有 SchoolClassStudent 型号。每所学校可以有不止一位校长,每所 class 可以有不止一位 class 位教师。

将有两个对象级权限:

  1. 学校校长将能够看到所有在他们学校注册的学生。他们将看不到其他学校的学生。
  2. Class 教师将能够看到注册到 class 的学生。他们将无法看到注册到同一所或不同学校的其他 classes 的学生。

我搜索了各种第 3 方 django 库来实现这种分层用户组架构。我已经看到 django-groups-manager, but it is a bit complicated for my issue. Then, I decided on django-mptt's registration of existing models 功能并提出模型实现,例如:

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
    )

通过这种方式,每个 SchoolClass 对象将拥有自己的 Groups,学校组是该特定 classes 组的父级学校。所以我现在可以使用 django 的 User 创建校长用户并将其分配给相关的家长组。以同样的方式,我也可以创建教师用户并将他们分配给他们 class 对象的子组。当校长或 class 老师想要查看他们的注册学生时,我可以通过过滤到他们的用户组来应用对象级权限。

我的问题是,这样做是否正确?为每个 school/class 个对象创建一个组有意义吗?

感谢 nigel222's suggestion, instead of using built-in django groups, I have overriden built-in django User model. I have also followed this 教程,它真的很有帮助。我的最新版本 models.py 如下(不要忘记覆盖默认值 User class,你需要通过将 AUTH_USER_MODEL = 'myapp.User' 添加到你的 settings.py 文件):

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
    )