【问题标题】:Basic group hierarchy in python djangopython django中的基本组层次结构
【发布时间】:2019-07-03 10:39:54
【问题描述】:

我正在使用注册学生的 django 构建学生注册系统。学生只能由他们的班主任和校长根据对象级别的权限查看。有SchoolClassStudent 型号。每所学校可以有多个校长,每个班级可以有多个班主任。

会有两个对象级权限:

  1. 校长将能够看到所有在他们学校注册的学生。他们将无法看到其他学校的学生。
  2. 班主任将能够看到注册到他们班级的学生。他们将无法看到注册到同一学校或不同学校的其他班级的学生。

我已经搜索了各种 3rd 方 django 库来实现这种分层用户组架构。我见过django-groups-manager,但这对我的问题来说有点复杂。然后,我决定使用django-mpttregistration 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,学校组是该特定学校的班级组的父级。所以我现在可以使用 django 的User 创建校长用户并将其分配给相关的父组。同样,我也可以创建教师用户并将他们分配给他们的班级对象的孩子组。当校长或班主任想要查看他们的注册学生时,我可以通过过滤到他们的用户组来应用对象级别的权限。

我的问题是,这样做是否正确?每个学校/班级对象创建一个组有意义吗?

【问题讨论】:

  • 除了过滤的数据库查询之外,您还需要什么?前任(对您的模型进行明显更改)Student.objects.filter(class__teacher=teacher)Student.objects.filter(class__school__principal=principal)。 (teacherprincipal 可能是User 中的request.user 实例,用于登录用户)。顺便说一句,学生与班级的关系不是多对多的吗?
  • 你可以认为一个学生只能注册一个班级。但正如我所说,每个班级可以有不止一位老师,每位老师都应该能够看到该班级的注册学生。因此我需要在我的模型中使用Group 而不是User
  • 与我之前的评论相同:您还可以过滤 Django 多对多关系。只是指出可能性。
  • 所以你提到的是SchoolClass 模型将有ManyToMany 字段到django 的内置User 模型。我根本不会使用 django 内置的Group。我说的对吗?
  • 是的,这是可能的。值得一读的Django多对多话题docs.djangoproject.com/en/2.2/topics/db/examples/many_to_many

标签: python django python-3.x django-models hierarchical-data


【解决方案1】:

感谢nigel222 的建议,我没有使用内置的django 组,而是覆盖了内置的django User 模型。我还关注了this 教程,这真的很有帮助。我最新版本的models.py 如下(不要忘记覆盖默认的User 类,您需要通过将AUTH_USER_MODEL = 'myapp.User' 添加到您的settings.py 文件来让django 知道它):

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
    )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    相关资源
    最近更新 更多