温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - Basic group hierarchy in python django
django django-models hierarchical-data python python-3.x

其他 - python django中的基本组层次结构

发布于 2020-03-27 10:59:17

我正在使用django进行学生注册的系统来构建学生注册系统。根据对象级别的权限,班级老师和校长只能查看学生。还有SchoolClassStudent模型。每所学校可以有不止一位校长,每班可以有不止一位班主任。

将有两个对象级别的权限:

  1. 校长将能够看到所有注册到学校的学生。他们将无法看到其他学校的学生。
  2. Class teachers will be able to see the students that are registered to their classes. They won't be able to see students registered to other classes in the same or different schools.

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 Groups, 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?

查看更多

查看更多

提问者
cagrias
被浏览
163
cagrias 2019-07-03 22:13

感谢nigel222的建议,我没有使用内置的django组,而是覆盖了内置的django User模型。我也遵循了教程,这确实很有帮助。我的最新版本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
    )