Как сократить время на выполнение этого кода в 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()]
        }
    )
Вернуться на верх