Django comments for authenticated users
Friday, 21st November, 2008 // 3:26 p.m.Yesterday I read a blog post by Theju regarding 'Using Django comments for authenticated user's. I recommend reading his post before reading this one as I suggest another approach to it.
Let's put some facts together. Django comment's had been refactored in Django 1.0 and now includes some great features like email, url and honeypot to prevent spam etc. Now using the django comments for authenticated user's is not a straight forward approach. You need to write some amount of code to make this happen.
If we take Theju's approach, he wrote a wrapper function around the default post_comment view which needs to be called when a comment is posted. Also the name, email and url fields in the comment form are pre-populated and hidden in the comment form.
<input type="text" name="author" id="id_author" type="hidden" value="{{ request.user.name }}" /> <input type="text" name="email" id="id_email" type="hidden" value="{{ request.user.email }}" /> <input type="text" name="url" id="id_url" type="hidden" value="{{ request.user.url }}" />
Rather than this approach, Theju actually made sure that the form cannot tampered and went a step ahead and made sure that the form is populated using javascript and made read-only. Good way. In the wrapper view he made sure that the name posted from the comment form matches with the name of the logged in user (Another check to fight spoofing).
if not (request.user.get_full_name() == request.POST['name'] or \ request.user.email == request.POST['email']):
We after seeing all this code I felt,
What's the need to write all this hidden input and again check for spoofing?
I felt that if we can write a custom template containing only the comment and the honeypot, timestamp etc we can retrieve the name, email and url in the view.
{% if request.user.is_authenticated %}
<h2>Leave a comment</h2>
{% get_comment_form for x as form %}
<form action="{% comment_form_target %}" method="POST">
{{ form.comment }}
{{ form.honeypot }}
{{ form.content_type }}
{{ form.object_pk }}
{{ form.timestamp }}
{{ form.security_hash }}
<input type="submit" value="Add comment" id="id_submit" />
</form>
{% endif %}
In this case we need not even write a wrapper because the default post_comment view populates the name, email & url if the user is authenticated. Check out django/contrib/comments/views/comments.py. Make sure that every User in User model has a name or the comment form would render back again with an error. If some User's don't have a name you need to write a wrapper function with a try, except block to catch the exception and use username instead of the name.
Some how using django comments for authenticated user's is not straight forward. It needs a bit of hacks. In my view if you are very serious about having comments for authenticated user's you can go ahead and create a comment model like
class Authenticated_comment(models.Model): belong_to = models.ForeignKey(Photo/ Post/ Anything) author = models.ForeignKey(User) comment = models.TextField() pub_date = models.DateTimeField()
You can also write this app generically too by pointing to any object in the database. Use this if you want comments for more than one model.
content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField(_('object ID')) content_object = generic.GenericForeignKey()
In case you don't want the hazzle of writing wrapper/ apps do check django-threadedcomments which has two separate models for authenticated user's comments and anonymous comments.
Comment Form
5 comments:
001// anedrinede// Monday, 29th December, 2008, 5:36 a.m.
vlucfxkcrzfupozwwell, hi admin adn people nice forum indeed. how's life? hope it's introduce branch ;)
002// Brian Neal// Tuesday, 30th December, 2008, 1:55 p.m.
Thanks for writing this up. I'm trying to decide if I should use the contributed comments framework. I need it for registered users only.
I checked in Django 1.0.2, and it now fills in the username if the get_full_name() is blank, so that is good.
My last question though. If a non-authenticated user crafts a form and POSTS, will it still go through with your method? Or does the form security features make this difficult?
Another question. If I decide to create my own AuthenticatedComment model, as you suggest, and I derive from the comments BaseCommentAbstractModel, can I then use the nice template tags? I'm thinking I need my own comment model, and I don't need the elaborate view machinery, but it sure would be nice to reuse the template tags the comments contrib app provides.
Thanks!
003// Disaswiny// Tuesday, 10th February, 2009, 7:35 p.m.
stimulating and educational, but would make something more on this topic?
004// Barbara// Thursday, 21st May, 2009, 9:06 a.m.
Thank you for writing this up - I found it just in time. For what it's worth, on my current project I'm using comments in sections that only authenticated users will ever see anyway. So I'm just trusting the @login_required decorator on my views, and leaving is_authenticated out of the templates.
005// anthony// Monday, 29th June, 2009, 3:46 a.m.
Well I have now rolled it out and working with an AJAX engine for a front end. What I would like to turn off is the requirement for having to be logged in, as this requires the user to be registered. Not something that I think is applicable to my site.
As you may have noticed in other posts I am using the YUI AJAX framework and I would recommend it to anyone that is using Django as an AJAX framework. http://www.casinoexperte.eu