Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticated commenting in Django 1.1?

(Now that Django 1.1 is in release candidate status, it could be a good time to ask this.)

I've been searing everywhere for ways to extend Django's comments app to support authenticated comments. After reading through the comments model a few times, I found that a ForeignKey to User already exists.

From django.contrib.comments.models:

class Comment(BaseCommentAbstractModel):
    """
    A user comment about some object.
    """

    # Who posted this comment? If ``user`` is set then it was an authenticated
    # user; otherwise at least user_name should have been set and the comment
    # was posted by a non-authenticated user.
    user        = models.ForeignKey(User, verbose_name=_('user'),
                    blank=True, null=True, related_name="%(class)s_comments")
    user_name   = models.CharField(_("user's name"), max_length=50, blank=True)
    user_email  = models.EmailField(_("user's email address"), blank=True)
    user_url    = models.URLField(_("user's URL"), blank=True)

I can't seem to get my head around setting user. If I use comments as is, even if I'm authenticated, it still seems to require the other fields. I'm guessing I should override the form and do it there? On top of that, if I use user, I should ignore the fact that user_name, user_email and user_url will be empty and just pull that information from a related profile model, correct?

While the answers could be quite trivial in the end, I'm just surprised that it hasn't been written or even talked about.

like image 640
Bryan Veloso Avatar asked Jul 22 '09 04:07

Bryan Veloso


1 Answers

WordPress and other systems make this a no-brainer. If you're logged in, the comment form should just "do the right thing" and remove the name/email/url fields. Isn't this exactly the kind of heavy lifting a framework is supposed to do for you?

Rather than dancing around with subclassing models for something that should be trivially easy, I find it simpler to build the form manually in the template and provide the hidden field values it needs. This works perfectly for sites that only accept comments from authenticated users:

{% if user.is_authenticated %}
{% get_comment_form for [object] as form %} 
<form action="{% comment_form_target %}" method="POST"> 
    {% csrf_token %}
    {{ form.comment }} 
    {{ form.honeypot }} 
    {{ form.content_type }} 
    {{ form.object_pk }} 
    {{ form.timestamp }} 
    {{ form.security_hash }} 
    <input type="hidden" name="next" value="{% url [the_view] [object].id %}" />
    <input type="submit" value="Add comment" id="id_submit" /> 
</form> 
{% else %}
    <p>Please <a href="{% url auth_login %}">log in</a> to leave a comment.</p>
{% endif %} 

Note that this will leave the honeypot field visible; you'll want to hide it in your CSS:

#id_honeypot {
    visibility:hidden;
}

If you want to enable comments either for anonymous or authenticated users, replace the auth_login line above with a standard call to a comment form.

like image 129
shacker Avatar answered Oct 14 '22 20:10

shacker