我有一个问题想要在响应中返回图像列表。 我创建了一个名为pest_id的外键,该外键链接到主知识库表。现在,如果我使用指定的方式,例如
KnowledgeBase.objects.values('id', 'pest_id', 'pest__name',
'pest__title', 'pestimages__image', 'front_image', 'cause',
'effect', 'remedy', 'prevention')
我得到了列表,但输出是
{
"id": 1473,
"pest_id": 249,
"pest__name": "Worker stuff little store three operation news. Move world affect small. Entire past face partner.",
"pest__title": "surya",
"pestimages__image": "extras/f4e8482c69e4e562d86149b45da8565e.jpg",
"front_image": "images/plant-3250.jpg",
"cause": "Summer popular music provide white.",
"effect": "That unit article practice feel nature.",
"remedy": "Car including hair before impact least scene tough. Generation job painting in develop issue mean half.",
"prevention": "Every business price step themselves own. Treatment guess far senior response. See a development last."
},
{
"id": 1473,
"pest_id": 249,
"pest__name": "Worker stuff little store three operation news. Move world affect small. Entire past face partner.",
"pest__title": "surya",
"pestimages__image": "extras/f2f05d15bf695d5bb45ca909887230f9.jpg",
"front_image": "images/plant-3250.jpg",
"cause": "Summer popular music provide white.",
"effect": "That unit article practice feel nature.",
"remedy": "Car including hair before impact least scene tough. Generation job painting in develop issue mean half.",
"prevention": "Every business price step themselves own. Treatment guess far senior response. See a development last."
},
但是预期的输出是:
{
"pest_id": 249,
"id": 1473,
"pest__name": "Worker stuff little store three operation news. Move world affect small. Entire past face partner.",
"pest__title": "surya",
"images": [
"extras/f4e8482c69e4e562d86149b45da8565e.jpg",
"extras/f2f05d15bf695d5bb45ca909887230f9.jpg",
"extras/ea1a1b02e734d1130c80e45880c106d3.jpg",
"extras/e66b165e767d45ac2ef046873a27ed29.jpg",
"extras/e54ed50db3e1079db9284bd30494de76.jpg",
"extras/de37d314715709b183d88ec82184330a.jpg",
"extras/dac29948d89054e2ede1b957b53d3ec6.jpg",
"extras/d7750c85b3e5d0b3cb7adaffa5474a11.jpg",
"extras/d468a3e96a0a7249a32e614ab7a4d8fa.jpg"
],
"front_image": "images/plant-3250.jpg",
"cause": "Summer popular music provide white.",
"effect": "That unit article practice feel nature.",
"remedy": "Car including hair before impact least scene tough. Generation job painting in develop issue mean half.",
"prevention": "Every business price step themselves own. Treatment guess far senior response. See a development last."
},
因此,您可以看到整个结果被重复的次数与PestImages表具有外键pest_id的次数相同。
我真正想要的是它应该以逗号分隔的值返回pestimages__image字段。
我需要更改型号吗?
我曾尝试寻找解决问题的解决方案,但是却找不到任何提示。
最终,我不得不编写自己的方法,这需要大量时间来处理结果。
id_list = KnowledgeBase.objects.values_list('id')
ResponseList = []
for id in range(len(id_list)):
kb = KnowledgeBase.objects.get(id=id_list[id][0])
pests = Pest.objects.get(id=kb.pest_id)
pestimg = [', '.join(map(str, x)) for x in PestImages.objects.filter(pest_id=id_list[id][0]).values_list('image')]
ResponseList.append(
{
'pest_id': kb.pest_id,
'id': id_list[id][0],
'pest__name': pests.name,
'pest__title': pests.title,
'images': pestimg,
'front_image': str(kb.front_image),
'cause': kb.cause,
'effect': kb.effect,
'remedy': kb.remedy,
'prevention': kb.prevention
}
)
return Response(ResponseList, status=HTTP_200_OK)
现在,尽管此功能可以达到我的目的,但是与普通方法的26ms相比,它需要1700ms的响应时间。
我的模特是:
class KnowledgeBase(models.Model):
pest = models.OneToOneField(Pest, on_delete=models.CASCADE)
cause = models.TextField()
front_image = models.ImageField(upload_to='images/', blank=False, null=False, default='images/plant-3250.jpg')
effect = models.TextField()
remedy = models.TextField()
prevention = models.TextField()
class PestImages(models.Model):
pest = models.ForeignKey('KnowledgeBase', on_delete=models.PROTECT)
image = models.ImageField(upload_to='extras')
class Pest(models.Model):
name = models.TextField()
title = models.CharField(max_length=255, unique=True)
有什么办法可以解决这个问题?
时差巨大:
〜30ms具有正常功能,具有冗余信息 正常功能:KnowledgeBase.objects.values(*)
〜1700ms(使用我的功能/使用序列化)。
我的函数已发布在上方,答案中列出了序列化方法。
答案 0 :(得分:1)
定义一个序列化器类
from rest_framework import serializers
class KnowledgeBaseSerializer(serializers.ModelSerializer):
images = serializers.SerializerMethodField()
pest__name = serializer.Charfield(source="pest.name")
pest__title = serializer.Charfield(source="pest.title")
def get_images(self, kb):
return [str(item) for item in kb.pestimages__image.all()]
class Meta:
model = KnowledgeBase
fields = ('id', 'pest_id', 'pest__name', 'pest__title', 'front_image', 'cause', 'effect', 'remedy', 'prevention', 'images')
然后
mydata = KnowledgeBaseSerializer(KnowledgeBase.objects.all(), many=True).data