#django #django-rest-framework
#django #django-rest-framework
Вопрос:
У меня проблема, когда я хочу вернуть список изображений в ответе. Я создал внешний ключ с именем 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)
Теперь, хотя эта функция служит моей цели, но для ответа требуется 1700 мс по сравнению с 26 мс обычного метода.
Мои модели:
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)
Есть ли какой-нибудь способ это исправить?
Разница во времени огромна:
~ 30 мс с нормальной функцией с избыточной информацией Нормальная функция: база знаний.объекты.значения (*)
~ 1700 мс с моей функцией / с использованием сериализации..
Моя функция опубликована выше, а метод сериализации указан в ответе.
Комментарии:
1. Пожалуйста, прокомментируйте, если кому-то нужна дополнительная информация, я добавлю пункты в вопросе.
2. Можете ли вы опубликовать свои модели?
3. Да, конечно, я добавлю их в вопрос.
4. Я обновил свой вопрос.
5. @JPG вы удалили свой ответ? Сериализация — это путь вперед для меня. Я проверю это.
Ответ №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
Комментарии:
1. django.core.exceptions. Неправильно сконфигурировано: имя поля
pest__name
недопустимо для моделиKnowledgeBase
. Возникает ошибка2. После исправления двух строк, pest__name = serializers . CharField(источник =»pest.name «) pest__title = сериализаторы. CharField(источник =»pest.title») Я получаю, AttributeError: объект «База знаний» не имеет атрибута «pestimages__image»
3. И использование сериализатора не сокращает время. Пожалуйста, проверьте загруженные изображения в вопросе.
4. Почему мое редактирование было отклонено? В ответе синтаксическая ошибка.