比如说,你有一个带有名称和电子邮件的模型,并使用Model Serializer通过Django Rest Framework序列化你的数据。输出将是这样的:
[{
"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将返回所有内容list[]
dict(instance)
与此类似:
data = list
for item in instance:
list.append(item.as_dict())
我不需要这是list
的{{1}},我希望他们做dict的词典吗?
dicts
这是我的to_representation()代码,我只能操作为单个实例返回的内容,所以它必须是一个dict,但我需要合并这个dict,而不是在serializer.data完全煮熟时在输出处堆叠
data = {}
for item in instance:
data[item.id] = item.as_dict()
我能够通过重新格式化原始的串行器输出来使其工作,但它肯定不是一个具有很大性能影响的干净解决方案:
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
根据@ zaphod100-10回答,我创建了一个自定义的ListSerializer类:
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
但是我的数据不能在“ListModelMixin”中存活:
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
它只返回实体ID的列表[]:serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
答案 0 :(得分:2)
为您的模型创建自定义ListSerializer并覆盖to_representation方法。
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_serializer_class元属性。
在此处阅读有关列表序列化程序的更多信息:
http://www.django-rest-framework.org/api-guide/serializers/#listserializer