Taking the ugly out of Django comments

Nov 07, 2008 Django

Django comments are pretty easy to implement - most of what you need to get access to the app and template tags is covered in the documentation:

http://docs.djangoproject.com/en/dev/ref/contrib/comments/

Regarding the template tags - you should be able to figure out what properties the comment object has by looking at the django_objects table in your database.

    {% load comments %}

    {% get_comment_list for entry as cmt_list %}
    {% for comment in cmt_list %}
    <div class="comment">
        <p><a href="{{ comment.user_url }}">{{ comment.user_name }}</a> - {{ comment.submit_date }}</p>
        {{ comment.comment }}
    </div>
    {% endfor %}

    <div class="comment_form">
        {% render_comment_form for entry %}
    </div>
Here's a helpful article for reference:

django comment fields [Revolution blahg]

But then the default preview and confirmation templates are sort of ugly:





To customize them a little, at least to have them extending your own base template so that they match the look and feel of your site, copy a few of the default templates out of Django:
    django/contrib/comments/templates/comments/preview.html
    django/contrib/comments/templates/comments/posted.html
into a '/comments/' folder in one of your project's template directories:
    belleville/templates/comments/preview.html
    belleville/templates/comments/posted.html
First things first, do a little cleanup on those templates now living in your project - make sure they're extending from your own base template, that block tags are using your tag names, etc.:
    {% extends "base.html" %}
    {% block page_title %}
        Preview your comment
    {% endblock %}
Now, one thing the default confirmation template doesn't have is a link back to the original entry. But I really don't want to make users go all the way back to the beginning to find their posted comments. A timed redirect might be slick, but I'll think about that later.

For now, I'm just adding a link to the template - using the one property of the comment object that I know has a relationship with the original post: the post object's primary key.
    {% block content %}
        <h1>Thank you for your comment.</h1>
        <a href="/viewid/{{ comment.object_pk }}/">Return to the original post</a>
    {% endblock %}
If you've looked at any of the other entries on this blog, you've seen that I use '/view/' with a slug as the pattern to view individual posts. But I don't have the slug here, so instead I'm using the pk and doing a quick redirect through another method, viewid.

Here's the pattern in the urls.py:
    url(r'^viewid/(?P<post_id>\w+)/*$',            views.viewid,           name='entry_viewbyid'),
No great mystery there. And here's the view method:
    def viewid(request, post_id):
        """
        """
        try:
            commented_entry = Post.objects.get(pk=post_id, publish=True)
            title = commented_entry.slug
            return HttpResponseRedirect('/view/%s/' % title)
        except ObjectDoesNotExist:
            return HttpResponseRedirect('/')
So when the pk value is passed in, we can get the post object and its slug, then redirect to the normal view. If we don't have the pk, there's nothing we can do but return the user to the blog's main page.