Improving Number of Queries Generated by Django Comment's render_comment_list Template Tag

19 Sep ยท by Tim Kamanin ยท 2 min read

One of my Django apps uses Django Comments. To show a list of comments on a page I use this simple built-in template tag:

{% render_comment_list for object %}

All is fine, but I noticed that it loads user object per every comment line. So if you have 50 comments on a page you'll end up with 50 queries to get comment author object. Not a good thing but can be easily fixed. What we need here is to leverage Django ORM's prefetch_related() and load user object with a comment list on one go. (Of course you can go with select_related here, but I prefer prefetch_related here). Ok the fix is easy, we need to create our custom render_custom_comment_list template tag, that inherits almost everything from the default render_comment_list except one thing: a queryset. Here 's how I do it: 1) Create custom template_tag file and call it like 'comment_tags.py' or whatever. 2) And then write the following contents:

# comment_tags.py
import django_comments
from django_comments.templatetags.comments import register, RenderCommentListNode


@register.tag
def render_custom_comment_list(parser, token):
"""
This is our custom comment list template tag.
"""
  return RenderCustomCommentListNode.handle_token(parser, token)


class RenderCustomCommentListNode(RenderCommentListNode):
"""
We created our custom Render Comment List Node that extends default RenderCommentListNode.
"""
def get_query_set(self, context):

  qs = super(RenderCustomCommentListNode, self).get_query_set(context)

  # The only additional thing we do here is we prefetch_related('user') to prefetch related user objects in one query.
  qs = qs.prefetch_related('user')

  return qs

As an outcome, instead of having 50+1 queries to get 50 comments out of the database, we got only 2: one to get comments out of db, another to get user objects. If you replace prefetch_related() with select_related() you will go down to only one query to load comments and user objects in one go. That simple!

Want to get more ๐Ÿ”ฅ tips like this one?

Subscribe to get notified about new dev tutorials