Сократите время, затрачиваемое на работу с api в Django Rest Framework

Вот модели, которые я создал, т.е. Video, Tag, Category, Exercise и Package_Exercise соответственно. и я хочу получить данные на основе объекта в package exercise и получить все данные из Exercise, т.е. url видео, тег и категорию каждого упражнения. Я написал код, но он занимает слишком много времени, как мне уменьшить время, затрачиваемое кодом? Каким должен быть лучший подход к решению подобных ситуаций? Какой подход будет лучшим, исходя из временной сложности.

class Video(models.Model):
video = models.FileField(upload_to='videos_uploaded',null=False,validators=[FileExtensionValidator(allowed_extensions=['MOV','avi','mp4','webm','mkv'])])
name = models.CharField(max_length=100)
thumbnail = models.ImageField(upload_to="video_thumbnails",null=False)
description = models.TextField(max_length=200)
created_by = models.ForeignKey('accounts.User', on_delete=models.CASCADE, related_name='videos_created_by')
updated_by = models.ForeignKey('accounts.User', on_delete=models.CASCADE, related_name='videos_updated_by')

def __str__(self):
    return self.name


class Tag(models.Model):
    name=models.CharField(max_length=100)
    def __str__(self):
        return self.name

class Category(models.Model):
    title=models.CharField(max_length=200)
    created_by = models.ForeignKey('accounts.User', on_delete=models.CASCADE, 
                                     related_name='catagoery_created_by')
    updated_by = models.ForeignKey('accounts.User', on_delete=models.CASCADE, 
                                    related_name='catagoery_exercise_updated_by')

    def __str__(self):
        return self.title



class Exercise(models.Model):
    name=models.CharField(max_length=100,null=False)
    description=models.TextField(max_length=300,null=False)
    video=models.ForeignKey(Video,on_delete=models.CASCADE,null=False)
    category=models.ForeignKey(Category,on_delete=models.CASCADE,null=False)
    tag=models.ManyToManyField(Tag,null=False)
    created_by = models.ForeignKey('accounts.User', on_delete=models.CASCADE, 
                                   related_name='exercise_created_by', null=False)
    updated_by = models.ForeignKey('accounts.User', on_delete=models.CASCADE, 
                                    related_name='exercise_updated_by', null=False)


    def __str__(self):
        return self.name

class Package_Exercise(models.Model):
  package = models.ForeignKey(Package,on_delete=models.CASCADE,related_name='package')
  exercise = models.ForeignKey(Exercise,on_delete=models.CASCADE)
  repetition = models.IntegerField()
  number_of_sets = models.IntegerField() 
  rest_time = models.IntegerField() 
  created_by = models.ForeignKey('accounts.User', on_delete=models.CASCADE, 
                              related_name='packages_exercise_created_by')
  updated_by = models.ForeignKey('accounts.User', on_delete=models.CASCADE, 
                              related_name='packages_exercise_updated_by')

Вот сериализатор занимает 2.3s для ~30 объектов данных в моделях.

class PackageSerializer(serializers.ModelSerializer):   
    exercises = serializers.SerializerMethodField()
    class Meta:
        model=Package
        fields= ['id','package_name','description','amount','is_public','public_doctor','thumbnail','exercises']


def get_exercises(self, obj):
    pkg_exercies = Package_Exercise.objects.filter(package = obj.id)
    sam = []
    for each in pkg_exercies:
        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
            }
        )
    return sam

Какие способы решения подобных ситуаций в API POST и GET

Сделайте новый сериализатор для модели package_excercise и используйте его в методе PackageSerializer следующим образом:

    def get_exercises(self, obj):
        pkg_exercies = Package_Exercise.objects.filter(package = obj.id)
        serializer = ExcerciseSerializer(data=pkg_exercies, many=True)
        serializer.is_valid()
        return serializer.data

Таким образом, вы будете использовать наилучший из возможных способов получения нужных данных, кроме того, вам не придется повторять один и тот же код в будущем.

Вернуться на верх