I have posts with tree comments in it. Comments have likes as well. I've managed to optimize SQL queries that usual comments, related to the post itself, don't create new queries, but answers to the other comments still create 3-4 new requests to the data base. Can I somehow reduce number of queries? I've been using prefetch_related for this purpose.
My Post model:
class Post(models.Model):
author = models.ForeignKey(
User,
on_delete=models.CASCADE
)
title = models.CharField(
max_length=200,
null=True,
blank=True
)
header_image = models.ImageField(
null=True,
blank=True,
upload_to="posts/headers",
help_text='Post will start from this image'
)
body = CharField(
max_length=500
)
post_date = models.DateTimeField(
auto_now_add=True
)
likes = models.ManyToManyField(
User,
through='UserPostRel',
related_name='likes',
help_text='Likes connected to the post',
)
def total_likes(self):
return self.likes.count()
Comment model
class Comment(models.Model):
user = models.ForeignKey(User, related_name='comment_author', on_delete=models.CASCADE)
post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE)
body = models.TextField(max_length=255)
comment_to_reply = models.ForeignKey("self", on_delete=models.CASCADE, null=True, blank=True, related_name='replies')
likes = models.ManyToManyField(User, through='CommentLikeRelation', related_name='comment_likes')
created_at = models.DateTimeField(auto_now_add=True)
def replies_count(self):
return self.replies.count()
def total_likes(self):
return self.likes.count()
def is_a_leaf(self):
return self.replies.exists()
def is_a_reply(self):
return self.comment_to_reply is not None
class CommentLikeRelation(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
comment = models.ForeignKey(Comment, on_delete=models.CASCADE)
View that process data
def get(self, request, *args, **kwargs):
current_user = request.user
user_profile = User.objects.get(slug=kwargs.get('slug'))
is_author = True if current_user == user_profile else False
comment_form = CommentForm()
Posts = Post.objects.filter(author=user_profile.id)
.select_related('author')
.prefetch_related('likes')
.prefetch_related(
'comments',
'comments__user',
'comments__likes',
'comments__comment_to_reply',
'comments__replies',
'comments__replies__user',
'comments__replies__likes',
)
.order_by('-post_date')
)
return render(request, self.template_name,
context={
'is_author': is_author,
'current_user': current_user,
'profile': user_profile,
'form': comment_form,
'posts': posts,
})