Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用django rest framerwork以字典形式返回对象列表,其中键作为对象id_Python_Django_Api_Dictionary_Django Rest Framework - Fatal编程技术网

Python 使用django rest framerwork以字典形式返回对象列表,其中键作为对象id

Python 使用django rest framerwork以字典形式返回对象列表,其中键作为对象id,python,django,api,dictionary,django-rest-framework,Python,Django,Api,Dictionary,Django Rest Framework,目前,我有一个ListAPIView,它返回一个对象字典列表: [ { id: 1, ...}, { id: 2, ...}, ... ] 我想将其更改为以id为键的字典格式: { "1": { id: 1, ...}, "2": { id: 2, ...}, ... } 如何使用Django Rest框架以这种方式自定义输出?目前,我正在客户端重新格式化,但我想在服务器端重新格式化。您可以遍历每个项目,并通过dict理解创建所需的词典。例如: >>>

目前,我有一个ListAPIView,它返回一个对象字典列表:

[
  { id: 1, ...},
  { id: 2, ...},
  ...
]
我想将其更改为以id为键的字典格式:

{
  "1": { id: 1, ...},
  "2": { id: 2, ...},
  ...
}

如何使用Django Rest框架以这种方式自定义输出?目前,我正在客户端重新格式化,但我想在服务器端重新格式化。

您可以遍历每个项目,并通过dict理解创建所需的词典。例如:

>>> l = [{ "id": 1, "x": 4}, { "id": 2, "x": 3}]
>>> {v["id"]: v for v in l}
{1: {'x': 4, 'id': 1}, 2: {'x': 3, 'id': 2}}

我认为您可以在序列化程序中实现
to_表示
函数

class MySerializer(serializers.Serializer):
    id = serializers.ReadOnlyField()
    field1 = serializers.ReadOnlyField()
    field2 = serializers.ReadOnlyField()

    def to_representation(self, data):
        res = super(MySerializer, self).to_representation(data)
        return {res['id']: res}
        # or you can fetch the id by data directly
        # return {str(data.id): res}

编辑:a和PYPI中提供的当前版本(
pip安装drf键控列表

这是一个双向的通用类(与上面的只读实现相比):

对于Py2,需要显式地调用
super
并替换指定的字典构造函数。通过将其分配给
列表序列化程序\u类
,并选择
键控列表序列化程序\u字段
(即用作dict键的字段),可以使用它:

键控列表\u序列化程序\u字段
应包含唯一值;上面的实现没有检查

class KeyedListSerializer(ListSerializer):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        meta = getattr(self.child, 'Meta', None)
        assert hasattr(meta, 'keyed_list_serializer_field'), \
            "Must provide a field name at keyed_list_serializer_field when using KeyedListSerializer"
        self._keyed_field = meta.keyed_list_serializer_field

    def to_internal_value(self, data):
        # syntax is py3 only
        data = [{**v, **{self._keyed_field: k}} for k, v in data.items()]
        return super().to_internal_value(data)

    def to_representation(self, data):
        response = super().to_representation(data)
        return {v.pop(self._keyed_field): v for v response}
class MySerializer(ModelSerializer):

    class Meta:
        list_serializer_class = KeyedListSerializer
        keyed_list_serializer_field = 'id'