Threadedcomments - csrf token and user_name - django

I am using django-threadedcomments. Everything works fine except 2 things: csrf token and user template tag.
Problem is, when user submits a comment, there is no csrf token for the form, so the form could not be validated server-side. Tried adding csrf token to the dictionaries that threaded-comments passes internal with no result; kept receiving errors (most of them telling that this-method takes only 2 arguments with 3 given). Tried to fix those methods to accept 3 arguments and just pass third one further; no success.
Did someone stumble upon the same problem in past and solved it? because this is not an acceptable solution for me:
MIDDLEWARE_CLASSES = (
#'django.middleware.csrf.CsrfViewMiddleware',
)
Second one - there is a HTML helper to get the user_id for the user who posted a comment. Is there an out of the box html helper to get the name of the user by id or would i have to write it myself?
http://code.google.com/p/django-threadedcomments/
Here is the code for the project, I cant really tell exactly which chunks of it should be posted here so I just give link to the entire project.
I am really stuck in here and any help would be welcomed.
Thanks in advance.

Tried adding csrf token to the
dictionaries that threaded-comments
passes internal with no result;
csrf_token is a template tag -- it shouldn't be passed as an argument somewhere.
I took a look at threadedcomments and it's based on contrib.comments with no html rendering, so it's up to you to insert the csrf_token in your template.
What does your TEMPLATE code look like that is displaying your form code?
If you have CsrfViewMiddleware enabled and you are using RequestContext in your view, you simply need to add {% csrf_token %} inside of your <form></form> tags.
As for getting the user name:
ThreadedComment is a subclasses of Comment which has a name property, or you could just access the User directly...
{% for comment in comments %
{{ comment.user.first_name }}
{{ comment.name }}
{% endfor %}

You should use {% csrf_token %} tag or #csrf_protect in a views

You can put your form in its own template and {% include %} it into your page template. As of Django 1.3, {% include %} can pass context variables to the included template. Here's what I'm using with django.contrib.comments instead of a templatetag:
...
{% include "comments/comment-form.html" with content_object=article user=request.user %}
...
{%csrf_token %} works in this included template because it's using your main view context.

Related

Add dynamic content

After a new article is posted (in a form via Ajax) on my Django news site, I want to return a link to the article.
To do so, I'm using a Template object that says:
if form.is_valid():
form.instance.user = request.user
new_article = form.save()
success = Template('<div id="panel_input" class="col-lg-4"> <h2 class="text-center"> Success </h2> <p class="text-center"> Your Article has been posted. You can see and edit details by clicking here. </p></div>')
context = Context({"article_id" : new_article.pk})
return HttpResponse(success.render(context))
The urlsConf for this looks like:
...
url(r'^article/(?P<article_id>\d+)/$', views.article, name='article'),
...
The problem is that I get an error because of {% url "article_manager:article" %}/{{ article_id }}. Apparently, I must pass the article_id inside the previous tag, since the urlsConf requires the id parameter.
But I also get an error when I put the second tag inside the first, like this:
{% url "article_manager:article" {{ article_id }} %}
I'm not sure how to accomplish this task, it doesn't seem to work with the tools I have. Does anyone have any suggestions?
Try {% url "article_manager:article" article_id=article_id %}
Maybe a little more explanation is needed: You were calling the template tag right {% url "namespace:name" %}. Remember that some templatetags can take arguments, in the *args, **kwargs form. The args can be any simple expression understood by the template language, including a context variable (no need to add double-braces). The kwargs follow the same rule, and have the form argument=expression. Thus, you can call some template tags with the form {% tag "exp" 1 request number=5 username=user.name %}

Include template displaying a form

What I want to do is include a form from a separate template at the bottom of a given page, lets say; "example.com/listdataandform/".
The form-template "form.html" displays the form as it should when the view is included in the URLConf. So I can view with "example.com/form/"
What I have so far goes something like this:
{% extends "base/base.html" %}
{% block title %} page title {% endblock %}
{% block content %}
<h2>some "scene" data</h2>
<ul>
{% for scene in scenes %}
<li>{{ scene.scene }} - {{ scene.date }}</li>
{% endfor %}
</ul>
{% include "tasks/form.html"%}
{% endblock %}
The code inside "block content" works as it should, since it is defined with it's corresponding view for the url "example.com/listdataandform/".
{% include "tasks/form.html"%}: This only displays the submit button from form.html, as expected. I realize by only doing this: {% include "tasks/form.html"%}, the corresponding view method is never executed to provide the "form"-template with data.
Is there any way to this without having to define the view to a specific pattern in urls.py, so that the form can be used without going to the that specified URL..?
So I guess the more general question is; how to include templates and provide them with data generated from a view?
Thanks.
For occasions like this, where I have something that needs to be included on every (or almost every) page, I use a custom context processor, which I then add to the TEMPLATE_CONTEXT_PROCESSORS in settings.py. You can add your form to the context by using this method.
Example:
common.py (this goes in the same folder as settings.py)
from myapp.forms import MyForm
def context(request):
c = {}
c['myform'] = MyForm()
return c
You can also do any processing required for the form here.
Then add it in your settings.py file:
settings.py
.
.
TEMPLATE_CONTEXT_PROCESSORS = (
'''
All the processors that are already there
'''
"myproject.common.context",
)
.
.
I realize by only doing this: {% include "tasks/form.html"%}, the corresponding view method is never executed to provide the "form"-template with data.
Indeed. You included a template, and it really means "included" - ie: "execute in the current context". The template knows nothing about your views, not even what a "view" is.
How does this help me executing the view for the included template to provide it with form data?
It doesn't. A Django "view" is not "a fraction of a template", it's really a request handler, iow a piece of code that takes an HTTP request and returns an HTTP response.
Your have to provide the form to the context one way or another. The possible places are:
in the view
in a context processor (if using a RequestContext)
in a middleware if using a TemplateResponse AND the TemplateResponse has not been rendered yet
in a custom template tag
In all cases this will just insert the form in your template's context - you'll still have to take care of the form processing when it's posted. There are different ways to address this problem but from what I guess of your use case (adding the same form and processing to a couple differents views of your own app), using a custom TemplateResponse subclass taking care of the form's initialisation and processing might just be the ticket.

Should I override a template for a Django (comments) framework or do the customization inside my own templates?

I am trying to customize the output of the comments list and forms using Django's comments framework.
Inside my own template, should I try to customize the comments by doing something like {% get_comment_form for object as form %} and carefully construct the form based on the form variable or should I override the form.html template and simply call {% render_comment_form for object %}?
Currently I'm leaning more toward using {% get_comment_form for object as form %} inside my own template, but using form.html as a guideline to write my own form.
On my websites, overriding form.html (and other comments templates) and simply calling {% render_comment_form for object %} works very well.
You should definitively have a form.html that is customized for your website's design. And in case you want a comment form to have a particular design, you can use get_comment_form.

CSRF problem: Django-registration app with my custom login-form in my base.html

Im using https://bitbucket.org/ubernostrum/django-registration/ for login and registration in Django.
But now im trying to add an login-form in my base.html, with a simple form
{% csrf_token %}... etc
The thing is when i login it says CSRF verification fails, i guess this is because the data isnt sent from templates/registration/login.html ?
Any idea how I should solve this in an easy way, will I have to write my own login-view?
Refresh the page of "http://*/accounts/register/" that contains your form not Forbidden after you add {% csrf_token %}.

How to override password_change error messages in django?

I have spent ages on the net how to override the change_password form in django. I created my forms and I can change my passwords successfully. Now I want to display my errors on the page.
(By the way , I'm using django-registration.)
The problem is I have to change error messages. In my template I'm using this function to display new_password1 errors :
{% if form.new_password1.errors %}
<div class="error_message"> blah </div>
{% endif %}
However it consists of all new_password1 errrors. I looked the docs and found that CharField has only reqiured, max and min. I need to check each specific errors of the new_password1 (confirmation error, required error and min,max) and produce my own error messages. Since the CharField doesn't have a matching keyword, I tried a clean method in my forms.py which looks like :
def clean_password2(self):
if 'new_password1' in self.cleaned_data and 'new_password2' in self.cleaned_data:
if self.cleaned_data['new_password1'] != self.cleaned_data['new_password2']:
raise forms.ValidationError(_(u"no match"))
return cleaned_data
Finally, I don't know how to check this clean_password2 validation in my template. When I wrote registration page, I can display all my errors by looping the errors. And it displays all overrided errors. This time it doesn't work. So my quesstions are:
1- How can i check all specific errors in my templates ? like if form.new_password1.required.errors
2- How can i display this clean_password2 messages ?
In django-speak, what you're referring to as the view is the template. It's rather confusing!
Update: I see that you define a clean_password2 function but you are checking for fields called new_password1, new_password2.
Unless you have a field called password2, that is the field that your clean method is validating.
The messages for clean_password2 are generated in {{ form.password2.errors }}, but to me, it sounds like you don't have a field called password2.
Change the name of your method to clean_new_password2.
{% if form.new_password1.errors %}{{ form.new_password1.errors }}{% endif %}
{% if form.new_password2.errors %}{{ form.new_password2.errors }}{% endif %}
Form field cleaning works per field.. you access the errors off the field object.
Like #Yuji said, use {% if form.non_field_errors %} in your template.
Now just a bit on usability. Concerning the user registration and password change form, the only non-field errors your can expect will be mismatching passwords, so unlike other forms where your going to print the non-field errors at the very beginning, for these forms it makes sense to print the one non-field error before the two password input fields, possibly wrapping them in a parent that has a red background, to make it more obvious that the values of the two fields are related and that the error concerns the two fields, not the form in general.