首页 > 解决方案 > 不同的字段类型序列化器 - Django Rest Framework

问题描述

您好,我有一个序列化程序,我想为 GET 请求设置一个字段类型,为 POST 请求设置另一个字段。

这些是我的序列化器:

class TypeSerializer(serializers.Serializer):
    id = serializers.CharField()
    name = serializers.CharField(max_length=50)
    colour = serializers.CharField(max_length=8)

class UserSerializer(serializers.Serializer):
    id = UUIDField(format="hex_verbose")
    name = serializers.CharField()
    type = TypeSerializer()

所以响应是这样的:

{
    "id": "987328lf-93ad-21ba-2648-h2u7b95d5cf",
    "name": "name",
    "type": {
        "id": "RANDOM_ID",
        "name": "Type 1",
        "colour": "#ffffff"
    }
}

这就是我在 GET 上想要的,但在 POST 上我想发送这样的有效负载:

{
    "name": "New name",
    "type": "RANDOM_ID"
}

我会收到 500 错误,因为类型应该是字典。

任何人都知道是否可以在不创建另一个序列化程序的情况下为 GET 设置一个字段,为 POST 设置另一个字段?

标签: djangoserializationdjango-rest-framework

解决方案


您需要覆盖to_internal_value方法:

class UserSerializer(serializers.Serializer):
    id = UUIDField(format="hex_verbose")
    name = serializers.CharField()
    type = TypeSerializer()

    def to_internal_value(self, data):
        type = data.get('type')
        if type:
            data['type'] = {'id': type}

        ret = super(UserSerializer, self).to_internal_value(data)

        # Probably here you will need to get type instance.

        return ret

我认为您想使用此序列化程序来创建用户,因此需要更多改进:

# Inherit from ModelSerializer !
class UserSerializer(serializers.ModelSerializer):
    id = UUIDField(format="hex_verbose")
    name = serializers.CharField()
    type = TypeSerializer()

    class Meta:
        model = User # Set model
        fields = ('id', 'name', 'type') # Set fields

    def to_internal_value(self, data):
        type = data.get('type')
        if type:
            data['type'] = {'id': type}

        ret = super(UserSerializer, self).to_internal_value(data)

        # Here i change dict to instance
        type = ret.get('type')
        if type:
            try:
                ret['type'] = Type.objects.get(id=type['id'])
            except Type.DoesNotExist:
                raise ValidationError({'type': ['Type with the given ID does not exist.']}
        return ret

推荐阅读