首页 > 解决方案 > Django Rest 框架返回字典而不是 OrderedDicts

问题描述

我有一个带有两个附加SerializerMethodField字段的序列化程序:

class BentoSerializer(ModelSerializer):
    zones = SerializerMethodField()
    lead_zone = SerializerMethodField()

    def get_zones(self, obj):
        zone_queryset = obj.get_zones()
        return ZoneSerializer(zone_queryset, many=True).data

    def get_lead_zone(self, obj):
        zone_queryset = obj.get_lead_zone()
        return ZoneSerializer(zone_queryset).data

    class Meta:
        model = Bento
        fields = ('lead_zone', 'zones', )

我需要从序列化器出来的数据是嵌套的 JSON(ZoneSerializer 包含SerializerMethodField自己的类似 s,以及正常的模型字段),但它以 OrderedDict 的形式出现。

有没有办法配置序列化器以BentoSerializer(obj).data返回嵌套的 JSON,我应该递归地将 OrderedDicts 转换为 dicts,还是有一些我不知道的其他序列化器方法用于获取非有序数据?

非常感谢!

PS:当前来自通过序列化器发送的工厂对象的示例数据:

[OrderedDict([('order', 1), ('columns', [OrderedDict([('order', 1), ('blocks', [OrderedDict([('order', 1), ('block_type', 'Text'), ('blockcontent', 'Cum inventore sed fugit aliquam doloribus. Alias exercitationem odit asperiores rerum qui aperiam cum fugit.'), ('heading', 'Adipisci possimus dolore assumenda sapiente velit amet odio doloremque.')])]), ('sticky', False), ('weight', 12), ('is_slideshow', False)])]), ('has_background_image', False), ('is_lead', False), ('is_slideshow', False), ('background_image', None), ('background_treatment', 'dark')])]
<class 'rest_framework.utils.serializer_helpers.ReturnList'>
{'lead_zone': {'background_image': None,
               'background_treatment': 'dark',
               'columns': [OrderedDict([('order', 1), ('blocks', [OrderedDict([('order', 1), ('block_type', 'Image'), ('blockcontent', '/media/media/2018/06/22/adatestfile_SfZMYPw.png'), ('heading', 'Reprehenderit officiis aliquid inventore enim quibusdam inventore beatae.')])]), ('sticky', False), ('weight', 12), ('is_slideshow', False)])],
               'has_background_image': False,
               'is_lead': True,
               'is_slideshow': False,
               'order': 1},
 'zones': [OrderedDict([('order', 1), ('columns', [OrderedDict([('order', 1), ('blocks', [OrderedDict([('order', 1), ('block_type', 'Text'), ('blockcontent', 'Cum inventore sed fugit aliquam doloribus. Alias exercitationem odit asperiores rerum qui aperiam cum fugit.'), ('heading', 'Adipisci possimus dolore assumenda sapiente velit amet odio doloremque.')])]), ('sticky', False), ('weight', 12), ('is_slideshow', False)])]), ('has_background_image', False), ('is_lead', False), ('is_slideshow', False), ('background_image', None), ('background_treatment', 'dark')])]}

标签: pythondjangoserializationdjango-rest-framework

解决方案


类/模型被序列化为 OrderedDict 类型,由Response方法通过此导入from rest_framework.response import Response结合 Django Rest 框架视图使用。它通常会返回内容类型中的数据,该内容类型在运行时通过DEFAULT_RENDERER_CLASSES项目设置分配,通过初始化时传递的序列化程序属性分配,或者由Accept请求期间发送的标头确定。详细信息可以在http://www.django-rest-framework.org/api-guide/renderers/的 DRF 文档中找到。

因此,调用Response(BentoSerializer(obj).data)应在通过 APIView 等视图或 ModelViewSet 上的路由传递时将 JSON 格式的数据返回给客户端。

但是,您也可以直接import json调用json.dumps(BentoSerializer(obj).data)并输出所需的 JSON。我在 django shell 中使用自己的序列化程序对此进行了测试。

编辑

请注意,您不能简单地转储日期时间......您最终可能不得不编写一个补丁来将日期时间和日期对象转换为您期望的格式。

例如。

def json_dt_patch(o):
    import datetime
    if isinstance(o, datetime.date) or isinstance(o, datetime.datetime):
        return o.strftime("%Y/%m/%d %H:%M:%S")
    return o

import json

json.dumps(data, default=json_dt_patch)

推荐阅读