This is my attempt at ticket #9819 which aims for better documentation to the comments framework. This is my second attempt at writing documentation and I have uploaded a patch to the ticket but wanted some feedback here without spamming the timeline.

Example of using the in-built comments app

  1. Follow the first three steps of the quick start guide in the documentation.
  2. Now suppose, you have an app (blog) with a model (Post) to which you want to attach comments. Let us also suppose that you have a template called blog_detail.html where you want to display the comments list and comment form.
  3. First, we should load the comment template tags in the blog_detail.html so that we can use it's functionality. So just like all other custom template tag libraries:
{% load comments %}
  1. Next, let us add the number of comments attached to the particular model instance of Post. For this we assume that a context variable object_pk is present which gives the id of the instance of Post.

    The usage of the get_comment_count tag is like below:

{% get_comment_count for object_pk as comment_count %}
<p>{{ comment_count }} comments have been posted.</p>

If you have the instance (say entry) of the model (Post) available in the context, then you can refer to it directly:

{% get_comment_count for entry as comment_count %}
<p>{{ comment_count }} comments have been posted.</p>
  1. To get a list of comments, we make use of the get_comment_list tag. This tag's usage is very similar to the get_comment_count tag. We need to remember that the get_comment_list returns a list of comments and hence we will have to iterate through them to display them:

    {% get_comment_list for object_pk as comment_list %}
    {% for comment in comment_list %}
    <p>Posted by: {{ comment.user_name }} on {{ comment.submit_date }}</p>
    <p>Comment: {{ comment.comment }}</p>
    {% endfor %}
  2. Finally, we display the comment form, enabling users to enter their comments. There are two ways of doing so. The first is when you want to display the comments template available under your comments/form.html. The other method gives you a chance to customize the form.

    The first method makes use of the render_comment_form tag. It's usage too is similar to the other two tags we have discussed above:

{% render_comment_form for entry %}

It looks for the form.html under the following directories (for our example):

Since we customize the form in the second method, we make use of another tag called get_comment_target. This tag on rendering gives the URL where the comment form is posted. Without any customization, get_comment_target
evaluates to /comments/post/. We use this tag in the form's action attribute. The get_comment_form tag renders a form for a model instance by creating a context variable. One can iterate over the form object to get individual fields. This gives you fine-grain control over the form:
{% for field in form %}
{% ifequal "comment" %}
  <!-- Customize the "comment" field, say, make CSS changes -->
{% endfor %}

But let's look at a simple example:

{% get_comment_form for entry as form %}
<!-- A context variable called form is created with the necessary hidden fields,
timestamps and security hashes -->
<form action="{% comment_form_target %}" method="POST">
  {{ form }}
    <td><input type="submit" name="preview" class="submit-post" value="Preview"></td>
  1. If you want your users to be able to flag comments (say for profanity), you can just direct them (by placing a link in your comment list) to /flag/{{ }}/. Similarly, a user with requisite permissions ("Can moderate comments") can approve and delete comments. This can also be done through the admin as you'll see later. You might also want to customize the following templates:

    • flag.html
    • flagged.html
    • approve.html
    • approved.html
    • delete.html
    • deleted.html

    found under the directory structure we saw for form.html.

  2. Suppose you want to export a feed of the latest comments, you can use the in-built LatestCommentFeed. Just enable it in your project's

from django.conf.urls.defaults import *
from django.contrib.comments.feeds import LatestCommentFeed

feeds = {
    'latest': LatestCommentFeed,

urlpatterns = patterns('',
# ...
  (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',
     {'feed_dict': feeds}),
# ...

Now you should have the latest comment feeds being served off /feeds/latest/.

  1. Now that we have the comments framework working, we might want to have some moderation setup to administer the comments. The comments framework comes in-built with generic comment moderation. The comment moderation has the following features (all of which or only certain can be enabled):

    • Enable comments for a particular model instance.
    • Close comments after a particular (user-defined) number of days.
    • Email new comments to the site-staff.
  2. To enable comment moderation, we subclass the CommentModerator and register it with the moderation features we want. Let us suppose we want to close comments after 7 days of posting and also send out an email to the site staff. In blog/, we register a comment moderator in the following way:

from django.contrib.comments.moderation import CommentModerator, moderator
from django.db import models

class Post(models.Model):
    title   = models.CharField(max_length = 255)
    content = models.TextField()
    posted_date = models.DateTimeField()

class PostModerator(CommentModerator):
    email_notification = True
    auto_close_field   = 'posted_date'
    # Close the comments after 7 days.
    close_after        = 7

moderator.register(Post, PostModerator)
  1. The generic comment moderation also has the facility to remove comments. These comments can then be moderated by any user who has access to the admin site and the Can moderate comments permission (can be set under the Users page in the admin).

  2. The moderator can Flag, Approve or Remove comments using the Action drop-down in the admin under the Comments page.


    Only a super-user will be able to delete comments from the database. Remove Comments only sets the is_public attribute to False.

Reusable App: Authenticated Comments

Tue 04 August 2009 by Thejaswi Puthraya

This app had been on my todo list for a long time. Today, no matter how much I tried to procrastinate, I could not ignore it and hence decided to scratch my itch and get it done. I swore I wouldn't even get up for a glass of water until …

read more

Yet another threaded comments app

Sat 10 January 2009 by Thejaswi Puthraya

A reusable threaded comments app

This week I am releasing code for yet another reusable app and yet another threaded-comments app. There are quite a few threaded comment apps around but the best one being this by Eric Florenzano.

The motive of releasing this code is not to compete with …

read more

Reusable recaptcha comments app

Sat 03 January 2009 by Thejaswi Puthraya

Reusable recaptcha comments app

One aim of Jacob's code for the comments framework in Django 1.0 was to make it as extensible as possible. At the same time this process should be quite generic and as DRY as possible.

It is here that I worked for a very long …

read more

Another Method: Comments for Authenticated Users

Fri 21 November 2008 by Thejaswi Puthraya

Another Method: Comments for Authenticated Users

In my previous post, I got a comment from Joshua Works who gave an interesting suggestion of not constructing fields for the name, email and url in the form as opposed to my method of using javascript to populate them. Each method has it's …

read more

Part 2: Django Comments for Authenticated Users

Thu 20 November 2008 by Thejaswi Puthraya

Part 2: Django Comments for Authenticated Users

In the previous part, we had seen how to setup the basic portions of the project. In this part, we are going to build on that and achieve using the comments framework to accept comments from registered users only.

Step - 2: Getting templates …

read more

Part 1: Django Comments for Authenticated Users

Wed 19 November 2008 by Thejaswi Puthraya

Part 1: Django Comments for Authenticated Users

Off late, I have not been hanging in the #django channel...but got an opportunity to do so a couple of days back. A user (I forgot his IRC nick), wanted to use django.contrib.comments to accept comments from authenticated users only …

read more