Оптимизация запросов Django rest framework
Есть модель поста и модель комментария.
class PostModel(models.Model):
8 """Модель поста"""
9
10 title = models.CharField(
11 max_length=120,
12 verbose_name="Заголовок статьи"
13 )
14 content = models.TextField("Содержание поста")
15 author = models.ForeignKey(
16 User,
17 on_delete=models.CASCADE,
18 related_name="posts",
19 verbose_name="Автор",
20 )
21 created = models.DateTimeField(
22 auto_now_add=True,
23 verbose_name="Дата создания"
24 )
25
26 def __str__(self):
27 return self.title
28
29 class Meta:
30 verbose_name = "Пост"
31 verbose_name_plural = "Посты"
class CommentModel(MPTTModel):
35 """Модель комментария"""
36 post = models.ForeignKey(
37 PostModel,
38 on_delete=models.CASCADE,
39 related_name="comments",
40 )
41 parent = TreeForeignKey('self',
42 on_delete=models.CASCADE,
43 null=True,
44 blank=True,
45 related_name='children')
46
47 author_name = models.CharField('Автор отзыва',
48 max_length=50,
49 default='Гость')
50 text = models.TextField("Текст комментария")
51 pub_date = models.DateTimeField(
52 "Дата создания комментария",
53 auto_now_add=True,
54 )
55 level = models.IntegerField(verbose_name='Уровень вложенности',
56 blank=True,
57 null=True)
58
59 def save(self, *args, **kwargs):
60 if self.parent != None:
>> 61 self.level = self.parent.level
>> 62 lvl = self.parent.level if self.parent.level else 0
63 print(lvl)
>> 64 if self.parent.level == 3:
65 raise serializers.ValidationError({"max_level": "Достигнут максимальный уровень вложенности"})
66 super(CommentModel, self).save(*args, **kwargs)
67
68 def __str__(self):
69 return f"Комментарий от пользователя {self.author_name} level {self.parent}"
70
71 class Meta:
72 verbose_name = "Комментарий"
73 verbose_name_plural = "Комментарии"
74
75 class MPTTMeta:
76 order_insertion_by = ['text']
И их сериализаторы
Сериализатор для вывода поста
41 class PostSerializer(WritableNestedModelSerializer,
42 serializers.ModelSerializer):
43 comments = CommentSerializer(many=True)
44 """Вывод всех постов"""
45
46
47 class Meta:
48 model = PostModel
49 fields = ("id",
50 "title",
51 "content",
52 "created",
53 "author",
54 "comments")
И сериализатор для вывода комментария к посту
6 class FilterCommentListSerializer(serializers.ListSerializer):
7 """Филтрация комментариев"""
8
9 def to_representation(self, data):
10 data = data.filter(parent=None)
11 return super().to_representation(data)
12
13
14 class RecursiveCommentSerializer(serializers.Serializer):
15 """Вывод древовидной структуры комментариев"""
16
17 def to_representation(self, value):
>> 18 serializer = self.parent.parent.__class__(value, context=self.context)
19 return serializer.data
20
21
22 class CommentSerializer(WritableNestedModelSerializer,
23 serializers.ModelSerializer):
24 """Вывод комментариев к посту"""
25
26 children = RecursiveCommentSerializer(many=True)
27
28 class Meta:
29 list_serializer_class = FilterCommentListSerializer
30 model = CommentModel
31 fields = ('id',
32 'post',
33 'author_name',
34 'text',
35 'pub_date',
36 'level',
37 'children',
38 )
И views
@api_view(['GET', "POST"])
10 def api_post(request):
11 """Вывод всех постов"""
12
13 if request.method == 'GET':
14
>> 15 posts = PostModel.objects.all()
16 serializer = PostSerializer(posts, many=True)
17 return Response(serializer.data)
18 elif request.method == "POST":
19 serializer = PostSerializer(data=request.data)
20 if serializer.is_valid():
21 serializer.save()
22 return Response(serializer.data,
23 status=status.HTTP_201_CREATED)
24 return Response(serializer.errors,
25 status=status.HTTP_400_BAD_REQUEST)
26
Необходимо оптимизировать запросы к бд.
