首页 > 解决方案 > 无法更新具有多对一关系的两个模型的嵌套序列化程序

问题描述

我创建了两个名为 office 和 phone 的模型,该电话保存了办公室电话(每个办公室可以有多个电话号码)用于使用这两个模型我创建了一个嵌套序列化程序和两个通用视图,一个用于发布和获取请求,另一个用于放置删除和检索我在发布,获取,删除,检索时没有问题,但如果更新方法无法更新电话号码,这里是代码:

办公室型号和电话型号:

class Office(models.Model):
    doctor=models.ForeignKey(Doctor,on_delete=models.CASCADE)
    title=models.CharField(max_length=100)
    address=models.TextField()
    location=models.FloatField()

    def __str__(self):
        return f"{self.title}({self.id})"


class OfficePhone(models.Model):
    office=models.ForeignKey(Office,related_name='phone',on_delete=models.CASCADE)
    phone=models.TextField()

电话和办公室序列化器:

class OfficeSerialzier(serializers.ModelSerializer):
    phone = OfficePhoneSerializer(many=True)

    def create(self, validated_data):
        phones = validated_data.pop('phone')
        office = Office.objects.create(**validated_data)
        for data in phones:
            p = OfficePhone(phone=data['phone'], office=office)
            p.save()
        return office


    def update(self, instance, validated_data):
        phone_numbers=validated_data.pop('phone')
        return super().update(instance, validated_data)

    class Meta():
        model = Office
        fields = ['id', 'doctor', 'title', 'address', 'location', 'phone']
        lookup_field = 'doctor'

办公室仿制药视图:

class OfficeDetail(generics.RetrieveUpdateDestroyAPIView):
    serializer_class=OfficeSerialzier
    queryset=Office.objects.all()


class officeListByDoctorID(generics.ListAPIView):
    serializer_class = OfficeSerialzier

    def get_queryset(self):
        return Office.objects.filter(doctor=self.kwargs['doctor'])

当我请求 put 方法无法在序列化程序中获取电话的 id 时,api 就像下面这样:

{
    "id": 25,
    "doctor": 2,
    "title": "new title updated",
    "address": "تهران",
    "location": 454454.0,
    "phone": [
        {
            "id": 33,
            "phone": "+914221036"
        },
        {
            "id": 34,
            "phone": "+9144562528"
        },
        {
            "id": 35,
            "phone": "+9144562528"
        }
    ]
}

标签: djangodjango-rest-frameworkdjango-viewsdjango-serializer

解决方案


每次我删除办公室的每个电话号码并重新重写时更新

class OfficeSerialzier(serializers.ModelSerializer):
    phone = OfficePhoneSerializer(many=True)

    def create(self, validated_data):
        phones = validated_data.pop('phone')
        office = Office.objects.create(**validated_data)
        for data in phones:
            p = OfficePhone(phone=data['phone'], office=office)
            p.save()
        return office


    def update(self, instance, validated_data):
        phone_numbers= validated_data.pop('phone')
        OfficePhone.objects.filter(office=instance.id).delete()
        for data in phone_numbers:
            OfficePhone.objects.create(office=instance,phone=data.get('phone'))
        return super().update(instance, validated_data)

    class Meta():
        model = Office
        fields = ['id', 'doctor', 'title', 'address', 'location', 'phone']
        lookup_field = 'doctor'

推荐阅读