不同的字段类型序列化程序-Django Rest Framework

时间:2018-12-05 12:43:06

标签: django serialization 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提供另一个字段吗?

2 个答案:

答案 0 :(得分:1)

您需要覆盖 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

答案 1 :(得分:1)

一种解决方法是使用2个字段-一个读取字段和一个写入字段:

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_read = TypeSerializer(read_only=True)

    # you could use a prrimary key related field 
    # instead if it is a model serializer;
    type = serializers.CharField(write_only=True) 

    def to_representation(self, instance):
        rep = super().to_representation(instance)

        # rename type_read to type
        rep['type'] = rep['type_read']
        del rep['type_read']
        return rep