If views catches error, reload page and display error - django

I don't know if this is possible with Django or not, but here's my question.
I have a form where users submit some stuff, and I want to know if I can catch an error in my views and then reload the page using the original template and throw the error in there, so the user can see it?
I have some code that returns the error I want to display, but is it possible to redirect to the original template of my view and insert this error code into there IF the form fails?
Bear in mind that roundup isnt value a user submits, but a value that is calculated from some other python code.
if roundup >= 1:
return HttpResponse("Price too low!")

You could add the error to your form in this way
if roundup >= 1:
form.add_error(None, "Price too low!")
return render(request, 'your_template', {'form': form})
and to show it the error in your template
{% for error in form.non_field_errors %}
<div class='alert alert-danger' role='alert'>
{{ error }}
</div>
{% endfor %}

Related

Django / an argument with HttpResponseRedirect is empty in my HTML page

In Views.py
return HttpResponseRedirect('add_scenes?submitted=True?linkToPrevScene=%s'%ScenePrevious)
ScenePrevious is a string containing "water2"
In my URL of add_scenes.html it works :
http://127.0.0.1:8000/scenes3d/add_scenes?submitted=True?linkToPrevScene=water2
But in the file add_scenes.html
{% if submitted %}
your scene was submitted successfully after {{ linkToPrevScene }}
{% else %}
this HTML code doesn't give output for {{ linkToPrevScene }} although {% if submitted %} is evaluated correctly
edit of my post:
This line also doesn't work if I replace the second ? by &
return HttpResponseRedirect('add_scenes?submitted=True&linkToPrevScene=%s'%ScenePrevious)
Sorry I couldn't comment but you need to pass the parameter linkToPrevScene through the view for you to receive it in the template.
**Note:**In Django You can not pass parameters with redirect. Your only bet is to pass them as a part of URL.
#...Rest of your view...
context['linkToPrevScene'] = Water2
redirect(reverse('add_scenes?submitted=True?linkToPrevScene=%s'%ScenePrevious, kwargs={ 'linkToPrevScene': Water2 }))
Use the links below for reference
Django documentaion:
Reverse
Redirect

Django: CSRF is incorrect or missing

I have seen a number of forums and posts but still couldn't get the handle of it. Here in django doc, it says
The CSRF middleware is activated by default in the MIDDLEWARE setting. If you override that setting, remember that 'django.middleware.csrf.CsrfViewMiddleware' should come before any view > middleware that assume that CSRF attacks have been dealt with.
If you disabled it, which is not recommended, you can use csrf_protect() on particular views you want to protect (see below).
In any template that uses a POST form, use the csrf_token tag inside the > element if the form is for an internal URL, e.g.:
form action
{% csrf_token %}
Based on that, in my html template I did simply:
<form id='frm' name='frm' method="post" action="{% url 'gettip' %}" >
{% csrf_token %}
<input type="text" name="tipid" name="tipid">
<input type="submit" value="Get Tip Value"/>
</form>
I expected the CSRF_token to create the hidden element since the middleware is already loaded. I see no element in the form and I get CSRF error.
The form is not associated with any model. I haven't used forms.py either. My current view is simply to output something:
def gettip(request):
if request.POST:
return HttpResponse('You requested a tip')
#from a weblink, i was told to add the following but it made no difference
context = {}
return render_to_response('tip.html',context, context_instance=RequestContext(request))
The error I am getting is obviously CSRF missing cos the hidden element is not there at all.
I am migrating from PHP and this is giving me a hard time. Though my form is not for login purposes, I couldn't get this one to work either for the same error. I am on django 1.10 and just want to get a positive response when form is submitted.
Don't use render_to_response, it's obsolete. Use render instead.
from django.shortcuts import render
def gettip(request):
if request.POST:
return HttpResponse('You requested a tip')
context = {}
return render(request, 'tip.html', context)
If the template containing the form is rendered by another view, you'll have to fix that view as well.

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 %}

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.

Threadedcomments - csrf token and user_name

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.