【问题标题】:Return list of objects as dictionary with keys as the objects id with django rest framerwork使用 django rest 框架将对象列表作为字典返回,键作为对象 id
【发布时间】:2015-07-07 22:50:53
【问题描述】:

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

[
  { id: 1, ...},
  { id: 2, ...},
  ...
]

我想将其更改为以 id 为键的字典格式:

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

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

【问题讨论】:

    标签: python django api dictionary django-rest-framework


    【解决方案1】:

    我认为你可以在你的序列化器中实现to_representation 函数。

    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}
    

    【讨论】:

      【解决方案2】:

      您可以遍历每个项目并使用字典理解创建您想要的字典。例如:

      >>> 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}}
      

      【讨论】:

        【解决方案3】:

        编辑:Github project 和 PYPI (pip install drf-keyed-list) 中提供的当前版本

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

        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}
        

        对于 Py2,您需要显式调用 super 并替换指示的字典构造函数。您可以通过将其分配给您的 list_serializer_class 并选择 keyed_list_serializer_field(即用作 dict 键的字段)来使用它:

        class MySerializer(ModelSerializer):
        
            class Meta:
                list_serializer_class = KeyedListSerializer
                keyed_list_serializer_field = 'id'
        

        keyed_list_serializer_field 应该包含唯一值;上面的实现没有检查。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-17
          • 1970-01-01
          • 1970-01-01
          • 2011-10-25
          • 2018-05-22
          • 2012-08-31
          • 1970-01-01
          • 2013-05-23
          相关资源
          最近更新 更多