Как валидировать данные по вторичной модели 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)