Как валидировать данные по вторичной модели Django rest (при добавлении или обновлении записи)

Необходимо при создании группы (и передаче списка студентов) проверять, чтобы в группе было меньше какого-то количества студентов, допустим, 20. Связь сущностей Группа-(fk)Студент. Студенты добавляются при создании группы, так и при редактировании (Значит, валидировать надо при post и put запросах). С ограничениями на уровне БД не получается, потому что ограничение на вторичную модель(студент) через группу не накладываются. Приходится решать через кастомную валидацию. Сейчас получается, что при добавлении одновременно с созданием, ограничение работает, а при добавлении после создания группы - не работает

models.py

class StudentGroup(models.Model):
    name = models.CharField(max_length=100, null=True, verbose_name='Название группы')
    course = models.ForeignKey('Course', null=True, on_delete=models.SET_NULL,
                               verbose_name='Выбранное направление подготовки')


    class Meta:
        verbose_name = 'Группа студентов'
        verbose_name_plural = 'Группы студентов'

serializers.py

class StudentGroupsSerializer(serializers.ModelSerializer):
    """Сериализатор для добавления студентов в группы в инпуте"""

    class Meta:
        model = StudentGroup
        fields = ['id', 'name', 'course', 'students']

    def validate(self, attrs):
        students = attrs['students']
        if len(students) > 20:
            raise serializers.ValidationError('Не допускается больше 20 студентов в группе')
        return attrs

tests.py

class StudentGroupsTestCase(APITestCase):
    def setUp(self) -> None:
        self.student_lst = [Student.objects.create(first_name=f'Student {i}') for i in range(21)]

    def test_student_assignment_while_group_creating(self):
        st = StudentGroup.objects.create(name='test_group1')
        st.students.set([self.student_lst[0], ])
        self.assertEqual(st.students.first(), self.student_lst[0], 'Студент не назначен')
        self.assertEqual(st.students.first().group_id, st.id, 'Группа студента при назначении не совпадает с назначаемой')


    def test_max_20_students_in_group(self):
        with self.assertRaises(ValidationError):
            st = StudentGroup.objects.create(name='test_group')
            st.students.set(self.student_lst)
            print('*' * 10, st.students.count(), '*' * 10)
Вернуться на верх