我将如何在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
如何实现更新subjects
?目前,我只能添加而不可以删除现有主题。
答案 0 :(得分:0)
在我们谈论多对多时,必须先将两个对象持久化,然后才能将它们彼此分配。
一旦有了,就可以简单地将一个添加到另一个的about集合中,如下所示(来源:https://docs.djangoproject.com/en/2.1/topics/db/examples/many_to_many/):
a1 = Article(headline='Django lets you build Web apps easily')
a1.save()
p1 = Publication(title='The Python Journal')
p1.save()
a1.publications.add(p1)
或者,一步:
new_publication = a1.publications.create(title='Highlights for Children')
我还没有找到如何表达“包含”的方法,但是下一步是删除不在新列表中的主题,并添加新列表而不是旧列表中的主题。排序列表或更好的散列可能更有效。但是我的python还不够好。
答案 1 :(得分:0)
这是一种解决方法。但我希望有人能发布更好的答案。这里的想法是先删除所有主题,然后再添加它们。但是,由于我们当然不能做teacher.subjects.all().delete()
,所以我们可以做
for existing_subject in teacher.subjects.all():
teacher.subjects.remove(existing_subject)
for subject in subjects:
teacher.subjects.add(subject)