Получить все связанные объекты множества для объекта Django, включая те, которые еще не сохранены в базе данных - PullRequest
0 голосов
/ 10 января 2020

Допустим, у меня есть следующие простые Django модели:

class Club(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name


class Student(models.Model):
    name = models.CharField(max_length=50, unique=True)
    club = models.ForeignKey(Club, on_delete=models.CASCADE, null=True, blank=True)

    def __str__(self):
        return self.name

И я создаю следующие объекты:

club1 = Club.objects.create(name="Club1")
student1 = Student.objects.create(name="Student1", club=club1)
print(club1.student_set.all())
# <QuerySet [<Student: Student1>]>

Теперь я собираюсь создать экземпляр второго ученика объект на клубном объекте, но НЕ ДАЛЕЕ сохранить его в базе данных. Есть ли способ связать всех учеников с club1 ДО того, как он был записан в БД? Похоже, использование стандартного подхода просто возвращает объекты, хранящиеся в БД:

student2 = Student(name="Student2", club=club1)
print(club1.student_set.all())
# <QuerySet [<Student: Student1>]>

# Goal is to get this:
# <QuerySet [<Student: Student1>, <Student: Student2>]>

Причина, по которой мне это нужно, заключается в некоторой проверке состояния промежуточных данных.

Ответы [ 2 ]

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

Вы можете добавить related_name attr, чтобы иметь легкий доступ ко всем студентам клуба. И вы можете проверить количество студентов перед сохранением.

class Student(models.Model):
    name = models.CharField(max_length=50, unique=True)
    club = models.ForeignKey(
        Club, 
        on_delete=models.CASCADE, 
        null=True, 
        blank=True,
        related_name='students', # add this related name and run migratioin
    )

    def __str__(self):
        return self.name

    def validate_club_students(self):
        if self.club.students.count() >= 3:
            raise ValidationError('The club already has 3 students!')

    def save(self, *arg, **kwargs):
        self.validate_club_students()
        super().save(*arg, **kwargs)

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

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

Если вы хотите выполнить проверку добавленного студента, вы должны использовать сигнал, который срабатывает при сохранении. Если при проверке возникает ошибка, сохранение не выполняется.

from django.db.models.signals import m2m_changed

m2m_changed.connect(student_set_changed, sender=Club.student_set.through) 

def student_set_changed(*args, **kwargs):
    # Do you validation
    return

Подробнее о том, как обрабатывать изменения в поле Many2Many в Django Документы

...