« Back

Django comment forms

« Older Post  |  Newer Post »

    Posted on July 12, 2010     

Django, the web framework has the 'wonderful' comment system, the is 'easy' to implement.  But there are a few things to get right in order to make them work.  Every time I come to implementing comments on a website I go through the same problems over and over again, and I don't think that the documentation makes this stuff clear enough. 

I don't want to blame the documentation to much… it's written for smart people, and I may just be a little slow on the uptake.  So this post is for me, so that I can refer to it each time I forget.  I hope that anyone else stuck on the same issues will get help from it too. 

If you are reading this post, you'll get nothing out of it unless you already have a good idea of Django's way of doing things, especially models, templates and views (you know, Django's MTV).

So, the assumption is you are writing some app and decide to let your users be able to comment.  Very nice of you, indeed.  So you go to the documentation and start implementing it, and try to post your first form...and you get a csrf error. 

To avoid that, follow this step by step. 

  • First step, go to your settings.py file, and add 'django.contrib.comments' to INSTALLED_APPS. Simple
  • Now, run python manage.py syncdb again to create the database tables needed for the comments.  This assumes, of course, that you have your database set up right. 
  • Now, add that to your urls.py file (the root one).
    urlpatterns = patterns('',
        ...
        (r'^comments/', include('django.contrib.comments.urls')),
        ...
    )
  • Okay, so far we have followed exactly what is suggested by Django.  Now, lets get the comment form working.  Open your views.py in your blog app.  Add this to the top of the file:
    from django.template import RequestContext
  • Now, scroll down to the view function that will call the template.  I am going to assume that you are using render_to_response.  Add this line,
    context_instance = RequestContext(request),)
    to the end of the return value.  It might look something like this:
    def main(request, year=0, month=0, slug=0, step=0):
        post = Post.objects.order_by("-published")
        count = post.count()
        if year and month and slug:
            post_single = post.filter(slug=slug)[0]
            return render_to_response('blog/blog_single.html', {'post':post_single,
                    'single':1,},
                    context_instance = RequestContext(request),)
  • All of that is rather easy (I think), but the problem comes when displaying the comment form.  If you have the default csrf protection in your middlewhere, it is going to throw an error when the user submits the comment. 
  • The normal way to display the comments is like this:
    {% render_comment_form for event %}
  • But to get rid of our error, we need to add the {% csrf_token %} into the form.  So we will have to do a custom display.
    {% render_comment_form for post %}
    <form action="{% comment_form_target %}" method="post">{% csrf_token %}
    {{ form }}
    </form>
  • Okay, unless you have changed something major in your settings.py file, it should work.  You can go further to change the re-direct page and use some CSS and javaScript to add some more personality to your form, but it should be working. 

I'll make sure that I get this blog's comments working properly now, so you can comment on this post :~)

« Older Post  |  Newer Post »


If you enjoy reading this blog, please subscribe | You might also like:  Linux Console Memory Game

 

Thank you for visiting

This is my personal blog, but I try to write things that you may find interesting or useful.  I'm currently working on a six month long project digging into the elements that make a blog meaningful. For more on that, visit MEANINGFUL BLOG PROJECT page

You may want to know a little about me personally, so start at the about page. 

If you find some of what is here interesting, or you want to follow the project through, why not subscribe.

Tweet