ModelViewSet - 更新嵌套字段

Che*_* Ju 17 python django django-rest-framework

我目前正在使用Django Rest Framwork处理Django.

我无法在嵌套对象字段中更新我的对象.


serializer.py

class OwnerSerializer(serializers.ModelSerializer):
    class Meta:
        model =  Owner
        fields = ('id', 'name')

class CarSerializer(serializers.ModelSerializer):
    owner = ownerSerializer(many=False, read_only=False) 
    class Meta:
        model =  Car
        fields = ('id', 'name', 'owner')
Run Code Online (Sandbox Code Playgroud)

view.py

class OwnerViewSet(viewsets.ModelViewSet):
    queryset = Owner.objects.all()
    serializer_class = OwnerSerializer

class CarViewSet(viewsets.ModelViewSet):
    serializer_class = CarSerializer
    queryset = Car.objects.all()

    def create(self, request):
        serialized = self.serializer_class(data=request.DATA)
        if serialized.is_valid():
            serialized.save()
            return Response(status=HTTP_202_ACCEPTED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)

当我这样做:

Request URL:http://localhost:9000/api/v1/cars/1/?format=json
Request Method:PUT
Request Paylod :
{
    "id":1,
    "name": "TEST", 
    "ower": {
        "id":1,
        "name": "owner_test"
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到以下回复:

The `.update()` method does not support writable nestedfields by default.
Write an explicit `.update()` method for serializer `app.serializers.CarSerializer`,
or set `read_only=True` on nested serializer fields.
Run Code Online (Sandbox Code Playgroud)

知道:

  • 我想在GET上保持所有者序列化;
  • 我们可以想象汽车被另一个物体嵌套等等......

如果我想在更新汽车时更改车主,该怎么办?

小智 8

有点晚了,但是,试试吧,

class OwnerSerializer(serializers.ModelSerializer):
    class Meta:
        model =  Owner
        fields = ('id', 'name')
        extra_kwargs = {
            'id': {
                'read_only': False, 
                'required': True
             }
        } #very important

    def create(self, validated_data):
        # As before.
        ...

    def update(self, instance, validated_data):
        # Update the  instance
        instance.some_field = validated_data['some_field']
        instance.save()

        # Delete any detail not included in the request
        owner_ids = [item['owner_id'] for item in validated_data['owners']]
        for owner in cars.owners.all():
            if owner.id not in owner_ids:
                owner.delete()

        # Create or update owner 
        for owner in validated_data['owners']:
            ownerObj = Owner.objects.get(pk=item['id'])
            if ownerObje:
                ownerObj.some_field=item['some_field']
                ....fields...
            else:
               ownerObj = Owner.create(car=instance,**owner)
            ownerObj.save()

        return instance
Run Code Online (Sandbox Code Playgroud)


pyc*_*333 2

以防万一有人偶然发现这个

在我的情况下有同样的错误,但将 read_only 设置为 True 为我修复了它。

    owner = ownerSerializer(many=False, read_only=True) 
Run Code Online (Sandbox Code Playgroud)

请注意,将数据发布到 api 时,该字段不会出现在表单中。

  • 问题是“更新汽车时如何更换车主?”。 (2认同)