简体   繁体   English

以互惠的方式连接两个模型

[英]Linking two model in reciprocal way

I'm trying to create a LMS (learning management system) system for my school.我正在尝试为我的学校创建一个 LMS(学习管理系统)系统。 In this system I'm trying to connect between origen_classroom model and the students and teacher model in a way that updating one of the models will update the others.在这个系统中,我试图在 origen_classroom 模型与学生和教师模型之间建立连接,更新模型之一将更新其他模型。 I try to use signals but it doesnt work on this model (It's working on the user model) attached is my code:我尝试使用信号,但它在这个模型上不起作用(它在用户模型上工作)附加的是我的代码:

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.dispatch import receiver
from django.db.models.signals import post_save
from .utils import upload_location, phone_regex
from materials.models import Subject


# Add fields to user module and uplaod image to the media location
class User(AbstractUser):
    USER_TYPE_CHOICES = (
        (1, 'student'),
        (2, 'teacher'),
    )
    user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES,
                                                 blank=True,
                                                 null=True
                                                 )  # user type
    date_of_birth = models.DateField(blank=True, null=True)
    phone_number = models.CharField(validators=[phone_regex],
                                    max_length=11,
                                    blank=True
                                    )  # validators should be a list
    profile_image = models.ImageField(upload_to=upload_location,
                                      blank=True,
                                      default='test.png',
                                      height_field='height_field',
                                      width_field='width_field',
                                      )
    height_field = models.IntegerField(default=0)
    width_field = models.IntegerField(default=0)

    class Meta:
        verbose_name_plural = "Users"

    def __str__(self):
        return self.username

# main student module


class Student(models.Model):
    user = models.OneToOneField(
        User, related_name='student', on_delete=models.CASCADE)
    origen_class = models.ForeignKey(
        'OrigenClass', on_delete=models.SET_NULL, blank=True, null=True)

    def __str__(self):
        return self.user.username

# main teacher module


class Teacher(models.Model):
    user = models.OneToOneField(
        User, related_name='teacher', on_delete=models.CASCADE)
    head_class = models.OneToOneField('OrigenClass', on_delete=models.SET_NULL, blank=True, null=True)
    teacher_subject = models.ForeignKey(Subject, on_delete=models.CASCADE, blank=True, null=True)

    def __str__(self):
        return self.user.username

# using signal to save changes in users into students or teachers
# TBD when changing from teacher to student need to check if already exist in one list and delete him
@receiver(post_save, sender=User)
def append_to_user_type(sender, **kwargs):
    if kwargs.get('created', False):
        if kwargs.get('instance').user_type == 2:
            Teacher.objects.get_or_create(user=kwargs.get('instance'))
        elif kwargs.get('instance').user_type == 1:
            Student.objects.get_or_create(user=kwargs.get('instance'))
    elif not kwargs.get('instance')._state.adding:
        if kwargs.get('instance').user_type == 2:
            Teacher.objects.get_or_create(user=kwargs.get('instance'))
        elif kwargs.get('instance').user_type == 1:
            Student.objects.get_or_create(user=kwargs.get('instance'))


class Grade(models.Model):
    GRADE_CHOICES = (
        (1, 'Grade 10'),
        (2, 'Grade 11'),
        (3, 'Grade 12'),
    )
    grade = models.PositiveSmallIntegerField(
        choices=GRADE_CHOICES, blank=True, null=True)  # Grade type

    def __str__(self):
        return self.GRADE_CHOICES[self.grade - 1][1]


class OrigenClass(models.Model):
    grade = models.ForeignKey(
        Grade, related_name='Grade', on_delete=models.CASCADE)
    class_name = models.PositiveIntegerField(blank=True, null=True)
    head_teacher = models.OneToOneField(
        Teacher, related_name='head_teacher', on_delete=models.CASCADE)
    students_members = models.ManyToManyField(Student, related_name='students')

    def __str__(self):
        return f'{self.grade} Class {self.class_name}'

@receiver(post_save, sender=Teacher)
def append_head_teacer_toclass(sender, **kwargs):
    if kwargs.get('created', False):
        OrigenClass.objects.get_or_create(head_teacher=kwargs.get('instance'))
    elif not kwargs.get('instance')._state.adding:
        OrigenClass.objects.get_or_create(head_teacher=kwargs.get('instance'))

I think you have some errors in your append_head_teacer_toclass(sender, **kwargs) .我认为您的append_head_teacer_toclass(sender, **kwargs)有一些错误。 When you are trying to create the OriginClass instance you are missing some mandatory fields which cannot be None , eg grade.当您尝试创建OriginClass实例时,您会遗漏一些不能为None必填字段,例如等级。

So when you are saving a Teacher instance where the OriginClass has not been set this should raise an error.因此,当您保存尚未设置OriginClass的教师实例时,这应该会引发错误。

If the associated OriginClass instance already exists, you are just getting the instance, not updating anything.如果关联的OriginClass实例已经存在,您只是获取该实例,而不是更新任何内容。 To update an instance you should use update_or_create .要更新实例,您应该使用update_or_create

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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