Сократите время, затрачиваемое на работу с 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
Таким образом, вы будете использовать наилучший из возможных способов получения нужных данных, кроме того, вам не придется повторять один и тот же код в будущем.