13

I'm totally understanding the documentation on expanding the Comments app in Django, and really would like to stick with the automatic functionality but...

In the current app, I have absolutely no use for an "URL" to be submitted along with a comment.

Being minimally invasive of the default setup, how can I prevent this field from showing up with the comment form?

Using Django 1, or Trunk, and as many generic/built-ins as possible (generic views, default comments set up, etc. I have only a single generic view wrapper so far).

anonymous coward
  • 12,594
  • 13
  • 55
  • 97

3 Answers3

17

I can't comment onto SmileyChris' post for some reason, so I am going to post it here. But, I ran into errors using just SmileyChris' response. You also have to overwrite the get_comment_create_data function because CommentForm is going to look for those Post keys that you removed. So here's my code after I removed three fields.

class SlimCommentForm(CommentForm):
"""
A comment form which matches the default djanago.contrib.comments one, but with 3 removed fields
"""
def get_comment_create_data(self):
    # Use the data of the superclass, and remove extra fields
    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,
    )


SlimCommentForm.base_fields.pop('url')
SlimCommentForm.base_fields.pop('email')
SlimCommentForm.base_fields.pop('name')

This is the function that you are overwriting

def get_comment_create_data(self):
    """
    Returns the dict of data to be used to create a comment. Subclasses in
    custom comment apps that override get_comment_model can override this
    method to add extra fields onto a custom comment model.
    """
    return dict(
        content_type = ContentType.objects.get_for_model(self.target_object),
        object_pk    = force_unicode(self.target_object._get_pk_val()),
        user_name    = self.cleaned_data["name"],
        user_email   = self.cleaned_data["email"],
        user_url     = self.cleaned_data["url"],
        comment      = self.cleaned_data["comment"],
        submit_date  = datetime.datetime.now(),
        site_id      = settings.SITE_ID,
        is_public    = True,
        is_removed   = False,
    )
killerbarney
  • 947
  • 10
  • 24
  • 5
    You'll need these import statements: from django.contrib.contenttypes.models import ContentType from django.utils.encoding import force_unicode from django.conf import settings import datetime – PhoebeB Jul 26 '11 at 12:50
  • Depending on the comments framework being extended, `django.contrib.comments` or `django_comments` (I gather latter is newer), `from django_comments.forms import CommentForm` – jozxyqk Sep 02 '14 at 14:35
10

This is well documented under customizing the comments framework.

All your app will use is get_form, returning a subclass of the CommentForm with the url field popped. Something like:

class NoURLCommentForm(CommentForm):
    """
    A comment form which matches the default djanago.contrib.comments one, but
    doesn't have a URL field.

    """
NoURLCommentForm.base_fields.pop('url')
StackExchange
  • 432
  • 2
  • 8
  • 22
SmileyChris
  • 10,578
  • 4
  • 40
  • 33
  • 8
    I agree the documentation is great, but I have to argue that finding my way to "base_fields" and using .pop() was not something I readily came across. Yes, the comments framework is well documented, but "this" is not. I agree that it's my responsibility to find that kind of thing, and I'm extremely grateful for your time and assistance! Thanks Bro! – anonymous coward Sep 22 '09 at 01:01
  • This throws errors in Django 1.4. You also need to override the get_comment_create_data method as mentioned in killerbarney's solution. – Jonathan Berger Feb 14 '13 at 00:37
5

My quick and dirty solution: I made the the 'email' and 'url' fields hidden fields, with an arbitrary value to get rid of 'this field is required' errors.

It's not elegant, but it's quick and I didn't have to subclass CommentForm. All the work of adding comments was done in the template, which is nice. It looks like this (warning: not tested, since it's a simplified version of my actual code):

{% get_comment_form for entry as form %}

<form action="{% comment_form_target %}" method="post"> {% csrf_token %}

{% for field in form %}

    {% if field.name != 'email' and field.name != 'url' %}
        <p> {{field.label}} {{field}} </p>
    {% endif %}

{% endfor %}

    <input type="hidden" name="email" value="foo@foo.foo" />
    <input type="hidden" name="url" value="http://www.foofoo.com" />

    <input type="hidden" name="next" value='{{BASE_URL}}thanks_for_your_comment/' />
    <input type="submit" name="post" class="submit-post" value="Post">
</form>
user416625
  • 213
  • 1
  • 4
  • 10