如何更新多对多Django REST?

如何更新多对多Django REST?,django,django-rest-framework,Django,Django Rest Framework,如何在Django REST框架中更新多对多关系 这是我的模型 class SchoolTeacher(AbstractBase): school = models.ForeignKey(School, on_delete=models.CASCADE, related_name='teachers') user = models.ForeignKey(User, on_delete=models.CASCADE, related_name

如何在Django REST框架中更新多对多关系

这是我的模型

class SchoolTeacher(AbstractBase):
    school = models.ForeignKey(School, on_delete=models.CASCADE, 
         related_name='teachers')
    user = models.ForeignKey(User, on_delete=models.CASCADE, 
         related_name='teacher_at',)
    subjects = models.ManyToManyField(SchoolSubject, 
        related_name='teachers')
这是我的序列化程序:

class SchoolTeacherSerializer(serializers.ModelSerializer):
   ....
   def create(self, validated_data):
    school_class = validated_data.get('school_class', None)
    stream = validated_data.get('stream', None)

    school_teacher_model_fields = [
        f.name for f in SchoolTeacher._meta.get_fields()]
    valid_teacher_data = {
        key: validated_data[key]
        for key in school_teacher_model_fields
        if key in validated_data.keys()
    }
    subjects = valid_teacher_data.pop('subjects')
    teacher = SchoolTeacher.objects.create(**valid_teacher_data)

    for subject in subjects:
        teacher.subjects.add(subject)

    self.add_class_teacher(stream, school_class, teacher)

    return teacher

def update(self, instance, validated_data):
    subjects = validated_data.pop('subjects')
    school_class = validated_data.get('school_class', None)
    stream = validated_data.get('stream', None)
    teacher = instance

    for (key, value) in validated_data.items():
        setattr(teacher, key, value)

    for subject in subjects:
        teacher.subjects.add(subject)

    teacher.save()

    return teacher

如何更新
主题
?目前,我只能添加而不能删除现有主题。

因为我们讨论的是多对多,两个对象都需要持久化,然后才能将它们分配给对方

一旦你有了它,你可以简单地将一个添加到另一个的集合中,就像这样(来源:):

或者,在一个步骤中:

new_publication = a1.publications.create(title='Highlights for Children')

我还没有发现如何表达“contains”,但下一步是删除不在新列表中的主题,并添加在新列表中但不在旧列表中的主题。使用排序列表或更好的散列可能更有效。但是我的python在这方面还不够好。

这里有一个解决方法。不过,我希望有人能给出更好的答案。这里的想法是先删除所有主题,然后添加它们。然而,由于我们当然不能做
教师.subjects.all().delete()
,所以我们可以做

    for existing_subject in teacher.subjects.all():
        teacher.subjects.remove(existing_subject)

    for subject in subjects:
        teacher.subjects.add(subject)

您是否只想将更新请求负载中传递的新科目保存到教师,并从教师中删除旧科目?这与我上面所做的没有什么不同,我想更新(放置或修补,这意味着删除未包含在负载中的科目),不仅仅是添加主题。@GrovelOde那么你的问题是什么?@GrovelOde好的,我想我现在明白了-你要求的是两个子集-你想删除不在新列表中的主题,并添加在新列表中但不在旧列表中的主题。我还没有找到如何做到这一点(“contains”操作),但这正是您可以尝试的。但我想,删除和重新添加所有内容也会一样好。
    for existing_subject in teacher.subjects.all():
        teacher.subjects.remove(existing_subject)

    for subject in subjects:
        teacher.subjects.add(subject)