Json 更改Django Rest框架中序列化对象的结构(模型内容之外的pull ID字段)

Json 更改Django Rest框架中序列化对象的结构(模型内容之外的pull ID字段),json,serialization,django-rest-framework,Json,Serialization,Django Rest Framework,比方说,您有一个名为和电子邮件的模型,并使用模型序列化程序用Django Rest框架序列化数据。输出如下所示: [{ "id": "1", "name": "Alex", "email": "alex@host.com" }, { "id": "2", "name": "Henry", "email": "henry@host.com" }] 是否有一种方法可以将唯一字段“拉”到模型内容的其余部分之外以获得此信息 { "1": {

比方说,您有一个名为和电子邮件的模型,并使用模型序列化程序用Django Rest框架序列化数据。输出如下所示:

[{
    "id": "1",
    "name": "Alex",
    "email": "alex@host.com"
}, {
    "id": "2",
    "name": "Henry",
    "email": "henry@host.com"
}]
是否有一种方法可以将唯一字段“拉”到模型内容的其余部分之外以获得此信息

{
    "1": {
        "name": "Alex",
        "email": "alex@host.com"
    },
    "2": {
        "name": "Henry",
        "email": "henry@host.com"
    }
}
我可以通过重写序列化程序的
to_representation()
方法(下面的代码示例)来“外部化”ID,但我无法摆脱基本的包装器-当前JRF将以
dict(instance)
list[]
返回所有内容,如下所示:

data = list
for item in instance:
    list.append(item.as_dict())
我不需要这是一个
目录的
列表,我想让它们成为目录的目录

data = {}
for item in instance:
    data[item.id] = item.as_dict()
这是我的to_representation()代码,我只能操作为单个实例返回的内容,因此它必须是一个dict,但我需要合并此dict,而不是在serializer.data完全煮熟时堆叠在输出端

def to_representation(self, instance):
    rep = OrderedDict()
    fields = self._readable_fields
    id_field = filter(lambda i: i.label == "ID", fields)[0]
    if id_field:
        id_atr = id_field.get_attribute(instance).__str__()
    else:
        raise Exception('cannot serialize models without ID field')
    rep[id_atr] = {}
    for field in fields:
        try:
            attribute = field.get_attribute(instance)
        except SkipField:
            continue
        if attribute is None:
            rep[id_atr][field.field_name] = None
        else:
            rep[id_atr][field.field_name] = field.to_representation(attribute)
    return rep
我可以通过重新格式化原始序列化程序输出使其正常工作,但这肯定不是一个干净的解决方案,会对性能产生很大影响:

def list(self, request, *args, **kwargs):
    _data = super(ChatMessageViewSet, self).list(request, *args, **kwargs)
    _resp = {}
    for item in _data.data:
        _id = item.get('id', None)
        if not _id:
            raise Exception('cannot serialize data without id field')
        _resp[_id] = {}
        for element in item:
            _resp[_id][element] = item[element]
    _data.data = _resp
    return _data
根据@zaphod100-10答案,我创建了一个自定义ListSerializer类:

class ChatMessageListSerializer(serializers.ListSerializer):

    def to_representation(self, data):

        iterable = data.all() if isinstance(data, models.Manager) else data
        _data = {}
        for item in iterable:
            _data[item.id] = self.child.to_representation(item)
        return _data
它以我需要的方式格式化数据:

但我的数据在“ListModelMixin”中无法保存:

serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

它只返回实体ID的列表[]:
[1L,2L,3L…]

为您的模型创建一个自定义ListSerializer,并覆盖to_表示方法

def to_representation(self, data):
    # convert your data which is a queryset or a 
    # list of objects to dict of dicts
    .....
    return dict_of_dicts
在主序列化程序类中创建ListSerializer后,添加list\u serializer\u类元属性

请在此处阅读有关列表序列化程序的详细信息:


有趣的是,数据不存在
ListModelMixin()
我已经更新了问题以详细说明问题。请再次检查代码。ListModelMixin没有做什么特殊的事情,只是将数据提供给many=true的序列化程序类。其余部分由序列化程序决定。你能粘贴你当前的代码吗?@zaphod100.00,是的,但我不知道数据在哪里被删除,这里的代码:@abolotnov是分页的?Paginator会将您的dict转换为一个列表,该列表将生成一个键列表。我想这就是正在发生的事情。我发现,to_representation()的输出必须是一个列表