如何序列化/反序列化Django模型

1 投票
1 回答
1142 浏览
提问于 2025-04-18 11:49

我现在的Django REST框架应用里有一个参数模型,里面有两个字段:“key”和“value”。目前,我的REST API要求客户端提供一个字典列表,这些字典的键总是“key”和“value”。

[
    {
        "key": "my_param_name_1",
        "value": "my_param_value_1"
    },
    {
        "key": "my_param_name_2",
        "value": "my_param_value_2"
    }
]

我知道这种请求格式可以改进:如果用一个字典,把“key”字段作为键,把“value”字段作为值,这样客户端的请求会更简单、更简洁。下面是我想要的格式的一个例子:

{
    "my_param_name_1": "my_param_value_1",
    "my_param_name_2": "my_param_value_2"
}

我现在有一个ParameterSerializer类,它是从serializers.Serializer继承过来的。这里是代码:

class ParameterSerializer(serializers.Serializer):
    key = serializers.CharField()    # This forces me to have "key" in every parameter dictionary...
    value = serializers.CharField()  # Same comment for "value".

    class Meta:
        models = Parameter

看起来rest_framework的序列化器只接受预先设定好的字典键(“key”和“value”),而不支持可变的字典键,这正是我想要的新格式所使用的。目前为止,我还没有找到让内置序列化器适应新格式的方法。

有没有什么建议我该怎么做?

1 个回答

1

我最终把这个序列化器去掉了,因为我真正需要做的是修改那个作为类成员使用的序列化器:

class ConfigurationSerializer(serializers.ModelSerializer):
    parameters = ParameterSerializer(many=True, source='parameter_set')

在继续之前,先说一下,Configuration模型包含了一组Parameter模型。

所以,在ConfigurationSerializer里,我用一个字段类变量替换了ParameterSerializer,这个变量是从serializers.WritableField继承来的:

class ConfigurationSerializer(serializers.ModelSerializer):
    parameters = ParametersField(source="parameter_set")

    class Meta:
        model = Configuration
        fields = ('id', 'version', 'resource', 'option', 'name', 'parameters')

下面是ParametersField的样子:

class ParametersField(serializers.WritableField):
    def from_native(self, parameters_dict):
        """
        Transform a dictionary of parameters to Django model objects.

        :param parameters_dict: A dictionary of parameters keyed by name.
        :type  parameters_dict: dict

        :returns: A list of Parameter model instances.
        :rtype: list
        """

        print(str([Parameter(key=name, value=value)
                  for name, value in parameters_dict.iteritems()]))
        return [Parameter(key=name, value=value)
                for name, value in parameters_dict.iteritems()]

    def to_native(self, parameter_set):
        """
        Transform the parameters to a dictionary.

        :param parameters: A list of Parameter model instances.
        :type  parameters: list

        :returns: A dictionary of parameters keyed by name.
        :rtype: dict
        """

        parameters_dict = {}
        for parameter in parameter_set.all():
            parameters_dict[parameter.key] = parameter.value
        return parameters_dict

WritableField类可以把任何模型序列化成任意的Python数据结构。因为我需要把数据以JSON格式返回给客户端,所以我选择把Configuration模型的Parameter模型集合转换成一个字典。

希望这对你有帮助!

撰写回答