如何编写DRF序列化程序来处理封装在模型中定义的数据字段的JSON包装器?

时间:2018-12-31 10:36:27

标签: json django-rest-framework django-serializer

我正在使用Django Rest Framework编写REST API,并且需要知道如何编写序列化程序来处理此json请求

{
    "user_form": {
        "fields": [
            {"email": "tom.finet@hotmail.co.uk"},
            {"password": "password"},
            {"profile": {
                "username": "Tom Finet",
                "bio": "I like running, a lot.",
                "location": "Switzerland"
            }}
        ]
    }
}

用户和概要文件对象都存在模型,因此我正在使用ModelSerializer来简化序列化。但是,相关的用户和个人资料数据包装在user_formfields信封中。因此,当我发出创建用户的POST请求时,服务器会用400吐出状态代码BadRequest

这是用户和配置文件序列化器

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = '__all__'

class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer()

    class Meta:
        model = User
        fields = ('email', 'password', 'profile')

    def create(self, validated_data):
        email_data = validated_data.pop('email')
        password_data = validated_data.pop('password')
        created, user = User.objects.get_or_create_user(
            email=email_data,
            password=password_data
        )
        return user

这是api创建视图:

def create(self, request):
    user_serializer = UserSerializer(data=request.data)
    if user_serializer.is_valid(raise_exception=True):
        user_serializer.save()
    return Response(
        user_serializer.data,
        status=status.HTTP_201_CREATED
    )

我想让序列化程序从指定的json请求创建用户,但是我不知道如何处理包裹用户和配置文件数据的信封。

1 个答案:

答案 0 :(得分:1)

根据我的评论,

考虑如下修改帖子的有效负载(客户端):

{
    "email": "tom.finet@hotmail.co.uk",
    "password": "password",
    "profile": {
        "username": "Tom Finet",
        "bio": "I like running, a lot.",
        "location": "Switzerland"
    }
}

在此之后,您当前的序列化程序类就足够了。

如果无法在客户端上更改帖子的有效负载,请考虑使用以下理解来对其进行推断,以在视图中手动实例化序列化程序:

serializer = UserSerializer(data={
    k: v
    for d in request.data.get('user_form').get('fields')
    for k, v in d.items()
})

if not serializer.is_valid():
    # handle invalid serializer error
    pass

# save the new model
serializer.save()