Как сократить время на выполнение этого кода в django rest framework
class Category:
title = models.CharField(max_length=50)
class Tag:
name = models.CharField(max_length=50)
class Video:
video = models.FileField(upload_to='xxx/')
class Exercise:
name = models.CharField(max_length=50)
video = models.ForeignKey(Video)
description = models.CharField(max_length=250)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
tag = models.ManyToManyField(tag, on_delete=models.CASCADE)
class Data:
relation = models.ForeignKey(Relation, on_delete=models.CASCADE)
exercise = models.ForeignKey(Exercise, on_delete=models.CASCADE)
Код для получения данных соответственно занимает слишком много времени, как мне уменьшить это или какие есть способы обработки подобных ситуаций
for each in Data:
sam.append(
{
"name": each.exercise.name,
"url": each.exercise.video.video.url,
"description": each.exercise.description,
"category": each.exercise.category.title,
"tag": each.exercise.tag.name
}
)
Во многих случаях медленной оказывается не база данных, а запросы, которые вы к ней посылаете. Это особенно верно при работе с большими базами данных, такими как Postgres. Если у вас есть запрос, который возвращает 5 миллионов строк и занимает 0,1 секунды на вашей машине, то при выполнении его на сервере баз данных он может занять в 100 раз больше времени. По возможности избегайте чтения базы данных в Python и делайте все на SQL (и просто передавайте Python результаты). Чтобы создать представление со всеми полями:
CREATE OR REPLACE VIEW all_exercises AS SELECT exercise.*, data.* FROM exercise JOIN data ON data.exercise_id = exercise.id;
SELECT * FROM all_exercises WHERE id = 1234; // this will run instantly even though the initial query was slow;
Вы захотите использовать select_related...[Django-doc] и prefetch_related... [Django-doc] здесь, чтобы уменьшить количество запросов, которые делает ваш цикл for, иначе он будет делать около 4 дополнительных запросов на каждый Data объект.
Так что вы можете сделать что-то вроде:
for each in Data.objects.select_related(
"exercise__video",
"exercise__category",
).prefetch_related(
"exercise__tag",
).all():
sam.append(
{
"name": each.exercise.name,
"url": each.exercise.video.video.url,
"description": each.exercise.description,
"category": each.exercise.category.title,
"tags": [t.name for t in each.exercise.tag.all()]
}
)