Customizing Django Comments: Remove Unwanted Fields

no-commentI recently added comments to a new Django site that I’m working on. Comments pose an interesting problem as they can have a number of “parents”. In my case, the parent might be a user’s “Want” a respondent’s “Have” or possibly another “Comment.”

In the process of researching the best way to architect Wantbox’s comments app, I read about “polymorphic associations“, “exclusive arcs” and Django’s ContentType framework. Using this knowledge, I contemplated recreating the comment wheel, since I wanted my comment form to just be a simple “Stack Overflow-type” comment-only field and not the larger “WordPress-type” name/email/website/comment.

As I explored Django’s comments framework deeper, I realized that recreating another comment app was a waste of my time and my end product would be far less feature rich than Django’s bundled commenting system. Below are my modifications which allowed me to quickly and easily twist Django comments into what I needed.

My Django Comment Modifications:

To customize the default comment form and comment list display, I created a “comments” directory in my root “templates” directory and simply overrode the two default comment templates “form.html” and “list.html”.

My custom “/templates/comments/form.html”:

{% load comments i18n %}
{% if user.is_authenticated %}
   <form action="{% comment_form_target %}" method="post">
        {% csrf_token %}
        {% if next %}<input name="next" type="hidden" value="{{ next }}" />{% endif %}
        {% for field in form %}
            {% if field.is_hidden %}
                {{ field }}
            {% else %}
                {% if field.name != "name" and field.name != "email" and field.name != "url" %}
                    {% if field.errors %}{{ field.errors }}{% endif %}
                    {{ field }}
                {% endif %}
            {% endif %}
        {% endfor %}
        <input class="submit-post" name="post" type="submit" value="{% trans " />
   </form>
{% else %}
    I'm sorry, but you must be <a href="javascript:alert('send to login page')">logged in</a> to submit comments.
{% endif %}

Which is only slightly different from the default Django comments form.html, primarily suppressing the display of the not-wanted and not-required “name”, “email” and “url” input fields.

My custom “/templates/comments/list.html”:

<div class="comment_start"></div>
{% for comment in comment_list %}
   <div class="comment">
      {{ comment.comment }}
      (from <a href="javascript:alert('show user profile/stats')">{{ comment.user }}</a> - {{ comment.submit_date|timesince }} ago)
   </div>
{% endfor %}

In the template where I want to invoke the comments form, I first call {% load comments %} and then {% render_comment_form for [object] %} to show the form, or {% render_comment_list for [object] %} to generate a list of the comments on the object (replace [object] with your appropriate object name). So easy.

This solution is working great for me, and still giving me all the other “free” stuff that comes with django comments (moderation, flagging, feeds, polymorphic associations, helpful template tags, etc…). The moral of this story: don’t recreate the wheel when an hour or two of research can give it to you for free.

NOTE: This blog post is based on my Stack Overflow answer to Ignacio’s question “How to extend the comments framework (django) by removing unnecesary fields?