如何将POST数据发送到嵌套的Serializer Django Rest Framework?

时间:2017-01-27 12:47:49

标签: django python-2.7 serialization django-rest-framework

我正在编写一个示例程序,可以将标签添加到todolist中。所以我创建了标签样本。但是当我把它添加到Todo序列化器时遇到了麻烦。

以下是我写的序列化器。

document.body.scrollTop

我尝试将数据作为POST发送到ToDo序列化程序。但是我如何将位置和标签详细信息发送到API视图。

APIView

class TagSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField(required=False, max_length=100)

    def create(self, validated_data):
        return Tag.objects.create(**validated_data)

class LocationSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    latitude = serializers.CharField(max_length=100)
    longitude = serializers.CharField(max_length=100) 

    def create(self, validated_data):
        return Location.objects.create(**validated_data)

class ToDoSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    work_id = serializers.CharField(max_length=100)
    tags = TagSerializer(many=True)
    location = LocationSerializer()

如何将数据作为POST传递给ToDoList。我是否必须在ToDoSerializer上编写自定义帖子视图?

模型

class ToDoList(APIView):
    def post(self, request, format=None):
        serializer = ToDoSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

2 个答案:

答案 0 :(得分:0)

您的请求POST数据应该看起来像嵌套结构,如序列化程序中声明的那样。你应该使用模型序列化器,因为否则你必须在create上提供自定义ToDoSerializer方法,因为常规序列化器不知道如何使用嵌套结构/模型

所以,我建议的是:

from rest_framework import serializers

class ToDoSerializer(serializers.ModelSerializer):
    tags = TagSerializer(many=True)
    location = LocationSerializer()

    class Meta:
        model = ToDo
        fields = ('tags', 'location', 'work_id', 'id')

您的帖子json应该如下:

{
    "work_id": 1,
    "tags" : [
        {"name": "blah"},
        {"name": "blahblah"}
    ],

    "location": {
        "latitude": 11.22,
        "longitude": 33.44
    }

}

答案 1 :(得分:0)

您需要处理ToDoSerializer serialzier的create方法。 docs writable-nested-representations

你可以尝试这样的事情:

def create(self, validated_data):
    location_data = validated_data.pop('location')
    tag_data = validated_data.pop('tags')
    location = Location.objects.create(**location_data)

    instance = ToDo.objects.create(location=location, **validated_data)

    for dct in tag_data:
        dct.pop('id', None)
        tag, created = Tag.objects.get_or_create(**dct)
        // tag = Tag.objects.create(**dct)
        instance.tags.add(tag)
    return instance