Как добавить данные в поле Many-To-Many в Django DRF

Я новичок в Django DRF, пытаюсь сделать проект спортивной школы. У меня есть модель для тренеров, классов и учеников. Вот урезанная версия, чтобы все было просто и легко:

class Student (models.Model):
    first_name = models.CharField(max_length = 50)
    last_name = models.CharField(max_length = 50)

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

 class Coach (models.Model):
    first_name = models.CharField(max_length = 50)
    last_name = models.CharField(max_length = 50)

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

 class ClassDetails (models.Model):
    class_name = models.CharField(max_length = 50)
    class_coach = models.ForeignKey(Coach, related_name='coach_classes')
    class_members = models.ManyToMany(Student, related_name='student_classes')

    def __str__(self):
        return self.class_name

Для того чтобы перечислить/добавить учеников в класс, я использую следующий сериализатор:

class ClassDetailsSerializer(serializers.ModelSerializer):
class Meta:
    model = ClassDetails
    fields = ['id','class_name', 'class_coach', 'class_members]
    read_only_fields = ('id', 'class_name', 'class_coach')

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

def member_add(self, request):
    my_class = ClassDetails.objects.get(pk = request.data['id']
    serializer = ClassDetailsSerializer(my_class, data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response('Member added', status.HTTP_201_CREATED)
    return Response(serializer.errors, status.HTTP_406_NOT_ACCEPTABLE)

Я отправляю тело POST следующего вида:

{
    "id": 2, <- class id
    "class_members": [20] <- student's id to add to the class members
}

Проблема в том, что независимо от того, сколько учеников в классе, вышеприведенный вариант удалит их всех и поставит вместо них ученика с идентификатором 20.

  • Как я могу сохранить текущих учеников и только добавить им новый id?
  • Как я могу также удалить id студента, не удаляя все данные в поле class_members?

Спасибо!

Я бы сказал определить вашу модель по-другому, вот пример -

Сначала определите детали вашего класса, например -

 class ClassDetails (models.Model):
    class_name = models.CharField(max_length = 50)

    def __str__(self):
        return self.class_name

затем определите своего Студента, например -

class Student (models.Model):
    first_name = models.CharField(max_length = 50)
    last_name = models.CharField(max_length = 50)
    classDetail = models.ForeignKey(ClassDetails)

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

и, наконец, ваш тренер как -

class Coach (models.Model):
    first_name = models.CharField(max_length = 50)
    last_name = models.CharField(max_length = 50)
    classDetail = models.ForeignKey(ClassDetails)
    
    def __str__(self):
        return f'{self.first_name} {self.last_name}'

таким образом, вы можете использовать вложенную функцию - теперь ваш ученик всегда связан с классом, а также ваш тренер связан с вашим классом.

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

class Coach (models.Model):
    first_name = models.CharField(max_length = 50)
    last_name = models.CharField(max_length = 50)
    classDetail = models.OneToOneField(ClassDetails)

Редактирование моего ответа на основе полученных данных --

для добавления нового идентификатора в поле типа manytomany сначала вам нужно будет создать студента, например

s = Student.objects.create()

и затем сделать что-то вроде

my_class = ClassDetails.objects.get(pk = request.data['id'])

чтобы получить правильный экземпляр classdetail и затем сделать что-то вроде -

my_class.class_members.add(s)

для добавления нового ученика в поле manytomany в ClassDetails

Вы можете настроить его в соответствии с вашими потребностями, надеюсь, это вам поможет.

Вернуться на верх