我有一个简单的API端点,它返回MyModel
的列表。
views.py:
@api_view(['GET'])
def index(request):
myModel = MyModel.objects.all()
serializer = MyModelSerializer(myModel, many=True)
return Response(serializer.data)
serializers.py
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ['field1', 'field2']
现在我想返回一个由主键索引的模型的序列化字典(这是一个CharField)。
{
'pk1':{
'field1': 'fo',
'field2': 'bar',
},
'pk2':{
'field1': 'fobar',
'field2': 'foo',
}
}
[编辑]根据要求,这是模型:
from django.db import models
class MyModel(models.Model):
id = models.CharField(primary_key=True)
field1 = models.FloatField(null=True)
field2 = models.FloatField(null=True)
答案 0 :(得分:0)
您可以遍历查询集。在index
视图中:
@api_view(['GET'])
def index(request)
data = dict()
for element in MyModel.objects.all():
dict[element.id] = {'field1': element.field1, 'field2': element.field2}
return Response(data)
答案 1 :(得分:0)
您可以在序列化程序中覆盖to_representation
方法
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ['field1', 'field2']
def to_representation(self, instance):
ret = super().to_representation(instance)
return {instance.pk: ret}
答案 2 :(得分:0)
您需要创建一个返回字典的自定义ListSerializer。
from django.db import models
from rest_framework import serializers
class DictSerializer(serializers.ListSerializer):
def to_representation(self, data):
iterable = data.all() if isinstance(data, models.Manager) else data
return [
(item.id, self.child.to_representation(item)) for item in iterable
]
@property
def data(self):
ret = super(DictSerializer, self).data
return serializers.ReturnDict(ret, serializer=self)
然后,当many = True时,您必须指定ModelSerializer应使用此自定义。您可以通过在ModelSerializer的Meta中设置list_serializer_class来完成此操作。
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ['field1', 'field2']
list_serializer_class = DictSerializer
答案 3 :(得分:0)
如果您想提高效率,可以遵循他的Gabriel Muj解决方案,但不会提供您想要的即用型解决方案。他的解决方案将提供如下输出:
[{
'pk1': {
'field1': 'fo',
'field2': 'bar',
}
},
{
'pk2': {
'field1': 'fobar',
'field2': 'foo',
}
}
]
首先根据他的解决方案更改序列化器:
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ['field1', 'field2']
def to_representation(self, instance):
ret = super().to_representation(instance)
return {instance.pk: ret}
但是要获得您所要的内容,您需要使用集合中的ChainMap。现在,您需要像这样更改视图:
from collections import ChainMap
@api_view(['GET'])
def index(request):
myModel = MyModel.objects.all()
serializer = MyModelSerializer(myModel, many=True)
data_dict = dict(ChainMap(*serializer.data))
return Response(data_dict)
对于此代码段,您需要确保其python 3.3+。这将提供良好的性能。在优化我的代码时,我发现这种解决方案不太繁琐。