Соединение двух моделей взаимным способом - PullRequest
0 голосов
/ 06 января 2020

Я пытаюсь создать систему LMS (система управления обучением) для моей школы. В этой системе я пытаюсь установить связь между моделью origen_classroom и моделью учеников и учителей таким образом, чтобы обновление одной из моделей обновляло другие. Я пытаюсь использовать сигналы, но это не работает на этой модели (это работает на пользовательской модели), прикрепленный мой код:

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'))

1 Ответ

0 голосов
/ 06 января 2020

Я думаю, у вас есть ошибки в вашем append_head_teacer_toclass(sender, **kwargs). Когда вы пытаетесь создать экземпляр OriginClass, вам не хватает некоторых обязательных полей, которые не могут быть None, например, оценка.

Таким образом, когда вы сохраняете экземпляр Учителя, где OriginClass не был установлен, это должно вызвать ошибку.

Если связанный экземпляр OriginClass уже существует, вы просто получаете экземпляр, ничего не обновляя. Для обновления экземпляра вы должны использовать update_or_create.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...