Context Navigation

Using Django's Free Comments

Django includes some basic commenting functionality that can save you a ton of time if you want to allow users to add comments to objects such as blog entries or photos. Django's free comments are flexible enough that they can be used on pretty much anything.

Set Up

The first thing you'll need to do is to add Django's comment packages to your INSTALLED_APPS in "settings.py":

INSTALLED_APPS =([...]'django.contrib.comments',)

If you're using custom views and not generic views, you'll need to add the following to the top of the relevant "urls.py" file. Generic views already include FreeComment, so you don't have to import it yourself.

You will need to update your database with the comments model. Stop your webserver if it's running, then use the django admin tool with the syncdb command.

In any template file in which you want to access comments, you'll have to load the comments packages before you access them with:

{% load comments %}

Below that, you're free to access the comments.

Adding Comment Counts to List and Archive Pages

The only data you need to access an object's comments is that object's id. If you have that, you can get the comments themselves, comment count, and other info.

django.views.generic.list_detail.object_list

In an object_list template, you can do the following to add the comment count to each of the blog entry listings. The following example assumes you have an app named "blog" with a class called "entry", which has fields called "title", "summary", and has a method called "get_absolute_url" which returns an absolute path to that entry's detail page.

Note: The class name should be always be referred to in all lowercase. For example, if the class contained inside the app named blog were actually named Entry, it would still be referred to as blog.entry.

In the date-based archives such as archive_year or archive_month, the collection you iterate through is called "object_list". archive_index is the only generic view with "latest".

Adding Comments to Detail Pages

Typically, you'll allow users to add comments through the detail page for an object. It's possible to allow them to do it elsewhere, but for simplicity's sake, this example only shows how to do it on detail pages. For any of the "detail" generic views such as django.views.generic.list_detail.object_detail or django.views.generic.date_based.object_detail, you'll have the object's id as "object.id", so getting the comment count is the same:

To get the list of comments, you call the following, which puts the list of comments in "comment_list":

{% get_free_comment_list for blog.entry object.id as comment_list %}

Each comment object in comment_list has the following bits of data:

comment.person_name - The comment poster's name.

comment.submit_date - The date and time the poster submitted the comment. You can pipe this through the "date" filter to format the date. (Shown in the example below)

comment.comment - The actual comment text. Don't forget to escape this to prevent code-injection attacks with the "escape" filter. (Shown in the example below)

comment.is_public - Whether or not the comment is public. (TODO: How do we set a comment's public or non-public status?)

comment.ip_address - The comment author's IP address.

comment.approved - Whether or not this comment has been approved by a staff member. (TODO: Where is this set or modified?)

And the following built-in methods:

comment.get_absolute_url - Returns an absolute URL to this comment by way of the content object's detail page. If a comment is attached to a blog entry located at "/blog/some-slug", this URL will look something like "/blog/some-slug/#c4", where "4" is the comments id number.

comment.get_content_object - Returns the object that this comment is a comment on.

As of this writing, the free comments don't allow for you to specify other bits of data to be included, such as the comment poster's e-mail address or URL. This may be changed in the future.

Free Comment Templates

Django has internal default templates for the various bits of comments-related code. (NOTE: Actually, I lied. Once ​these patches are applied, it will. Until then, you'll have to specify your own templates for "free_preview.html" and "posted.html".)

You can override any of these built in templates by creating a "comments/" folder in your templates folder with any or all of the following files:

Post Comment Form (freeform.html)

This template holds the form code that is used by the user to post a comment. In the above example, this is included like so:

Example

Wrapping post_free_comment to change the redirect url

At this time django.contrib.comments.views.comments has hard-coded, on its post_free_comment method, a redirection address to posted.html. If you want your comments to redirect to the original page that the comment was posted from, you can wrap the post_free_comment method and add a redirect to another after the comment creation. The URL can be passed as a hidden parameter in freeform.html
To do this you first need to create a wrapper in views.py

After you have your view you need to point the requests to that view instead of the default comments view
To do this, before this line

(r'^comments/', include('django.contrib.comments.urls.comments')),

add this line:

(r'^comments/postfree/','views.my_post_free_comment'),

And change the form to include the URL as a hidden field. The problem is: How do I get the current url in a template variable?. To do this you need to activate the template context processor called request adding the following code to settings.py

Once your request context processor is activated you will have the variable request available in your templates. With it you can get request.get_full_path to print the current URL. Make your freeform.html look like this: