Django: Remove excess comment fields

July 31, 2011

When playing with the Django comments framework, I realised that it asks for fields which are totally superfluous to my app. I don't need an email address and url attached to every comment, especially as only authorised users are able to comment, and if the comment is registered to the user object, why do I need to store a url and email for each comment?

One of the issues I found with the default comment framework documentation is it clearly discusses the issues surrounding adding new fields to the comment framework, but is much more cagey about their removal. Turns out, you can do it, but it isn't clear from the documentation. With reference to the documentation on how to create custom comments apps, and with the help of the following on Stack Overflow (killerbarney), the solution is quite straightforward.

I created a new app for custom comments, here called 'custom_comments'. Then I added the following to the custom_comments/forms.py file.

from django.contrib.comments.forms import CommentForm
from django.utils.encoding import force_unicode
from django.contrib.contenttypes.models import ContentType
from django.conf import settings

import datetime

class LightCommentForm(CommentForm):
    """
    A lighter comment form.
    """
    def get_comment_create_data(self):
        """
        This needs to be overwritten to remove the fields from the class
        """
        return dict(
            content_type = ContentType.objects.get_for_model(self.target_object),
            object_pk    = force_unicode(self.target_object._get_pk_val()),
            comment      = self.cleaned_data["comment"],
            submit_date  = datetime.datetime.now(),
            site_id      = settings.SITE_ID,
            is_public    = True,
            is_removed   = False,
        )
    
LightCommentForm.base_fields.pop('email')
LightCommentForm.base_fields.pop('url')

That removes the email and url fields from the default CommentForm. The next step is to register the app with the settings.py

INSTALLED_APPS (
    'custom_comments',
)

COMMENTS_APP = 'custom_comments'

Finally, add a couple of overrides to the __init__.py in the custom_comments app, to make sure that it uses the new form for requests to get_form().

from django.contrib.comments.models import Comment

from custom_comments.forms import LightCommentForm

def get_model():
    return Comment

def get_form():
    return LightCommentForm

And that should be it, when you now call the get_form(), you'll get a form which doesn't have the email and url fields included.

The Django documentation does suggest that if you don't want to rewrite the templates, you can also use BaseCommentAbstractModel to remove or substantially alter the comment model - one for another day.