Django Form Submission Error - django

I have this recurring problem with form submission in Django, and the frustrating part is that I'm not sure how to interpret what's happening. Essentially I have different pages with form submissions on them. Some of them work as following
localhost/page/formpage--> localhost/page/receivingpage
which is what I expect. Othertimes, it goes to a page like this
localhost/page/formpage--> localhost/page/formpage/recevingpage
and the screen shows a blank form page, which is not what I expect. I'm not sure how to interpret this, and I'm not sure where to look for errors in my code. I think I don't fully understand what's going on when I submit a form, how does it generate a URL after I press 'submit'?
Edit: here is my html form:
<!DOCTYPE HTML>
<html>
<div>
<p>Entry Form</p>
<form action= "user" method="post" >
{% csrf_token %}
<p><label for="id_username">Username:</label>
<input id="id_username" type="text" name="username"" /></p>
<p><label for="id_password">Password</label>
<input type="password" name="password" id="id_password" /></p>
<input type="submit" value="Submit" />
</form>
</div>
</html>
I suspect it isn't the form, I have it on another application and it works... the trouble is I don't know if it's the view, the template, or w/e, so I'll update the post with info as people request it.

I'd recommend putting in an action using the url template tag. With that, you will know for certain where the form is going to end up:
<form action="{% url 'user-url-name' %}" method="post">
The url tag will be an absolute url. Without this, you're going to end up at a relative url depending on where in your application the user submits the form, which can be quite confusing during development and not entirely correct.

Using {% url %} tag is the proper way to do. Your problem can also be solved by adding a forward slash / to the action attribute like this:
<form action="/user" method="post" >
Hope this helps!

Related

django parameter via get not working while forming direct url

Base URL:
path('api/product/',
include(('store.urls', 'store'),
namespace='api-product')),
Store URL:
path('invoice-pdf-get/',
invoice.InvoiceToPdf.as_view(),
name='invoice-pdf-get'),
HTML:
<html>
<body>
<form method="get" action="{% url 'api-product:invoice-pdf-get' %}?R={{ invoice.invoice_unique_number }}">
<input type="submit" value="Generate PDF">
</form>
</body>
</html>
When I hit the button, I get the url in browser as:
http://localhost:8000/api/product/invoice-pdf-get/?
Where as expecting:
http://localhost:8000/api/product/invoice-pdf-get/?invoice_number=SOMEKEY
Though if I submit a hidden type input via form, I get the expected result but I was reading: Daniel Roseman SO answer. to pass parameter via GET.
Though inspect shows the URL (see image) but why am I not getting expected result?
When a form is submitted via GET, the values in the form are sent as the querystring. This overrides any querystring in the action URL. See this SO answer for example.
You should put your value as a hidden input in the form itself.
<form method="get" action="{% url 'api-product:invoice-pdf-get' %}">
<input type="hidden" name="R" value="{{ invoice.invoice_unique_number }}">
<input type="submit" value="Generate PDF">
</form>

How to disable intermediate signout page in Django allauth

How to disable the intermediate signout page from django allauth. When the user clicks on the signout link on my site I want him to logout right away, I want to remove this intermediate page
Set ACCOUNT_LOGOUT_ON_GET to True in your settings.
Also see the documentation
Using a GET request is probably a bad idea due to browsers prefetching urls from the URL bar. Chrome (as of right now) is pretty bad for this; it'll send a GET request to pages it think you'll hit enter on when typing in your URL bar.
Plus, people can add a link such as <img src="https://example.com/account/logout/"> and you'll be logged out. That's not a security risk since it's logging you out, but it is certainly annoying for your users.
Instead, you should consider using a POST request using a form with CSRF. Django Allauth already comes with this. Here's the <form> from the intermediate signout page:
<form method="post" action="{% url 'account_logout' %}">
{% csrf_token %}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}"/>
{% endif %}
<button class="STYLE_ME" type="submit">Logout</button>
</form>
In my case, I just added this to the site header and made the submit <button> look like every other link using CSS so it feels the same to them, but the form will use a POST request.
But if that's not a solution you can implement for any reason, open your settings.py file (or your main settings file) and set:
ACCOUNT_LOGOUT_ON_GET = True
^ The above setting will do what you need. For further Django Allauth settings, check out their configuration page.
Here's another shortcut for preserving the POST request, if you don't want to mess with styling the form button with something like this:
Hide the form:
<form style='display: none;' method="post" action="{% url 'account_logout' %}">
{% csrf_token %}
<input type="hidden" name="next" value="/redirect_target/"/>
<button id="signOutBtn" type="submit">Logout</button>
</form>
Submit with a click event attached to whatever element you've already styled:
$(document).on('click', '#signOutLink', function() {
$('#signOutBtn').click()
});

How to properly use the django built-in login view

I'm just getting started with Django, and I'm trying to use built-in features as much as possible. As such, for user login, I'm using the built-in login view, and assigning it to the base url of my site:
urlpatterns=patterns('django.contrib.auth.views',
url(r'^/$','login',{'template':'mytemplate.html'}),
mytemplate.html looks something like this:
<!DOCTYPE html>
<html>
<body>
{%if form.errors %}
<p> Invalid username/password combination, please try again </p>
{% endif %}
<h1>Welcome to My Site!</h1>
<form action="{% url django.contrib.auth.views.login %}" method="post">
{% csrf_token %}
{{form.username.label_tag}}{{form.username}}
{{form.password.label_tag}}{{form.password}}
<input type="submit" id="submit" name="submit" value="Sign in" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
forgot username/password<br />
new user
</body>
</html>
my problem is, the template doesn't appear to be getting passed any of the context it's supposed to. In the rendered HTML, all of my variable tags simply disappear (i.e. rather than being replaced by the appropriate values, thay are replaced with nothing).
I imagine I'm skipping some critical step, but I can't figure out what it is. Any ideas?
You need to change from 'template' to 'template_name'
urlpatterns=patterns('django.contrib.auth.views',
url(r'^/$','login',{'template_name':'mytemplate.html'}),
https://docs.djangoproject.com/en/1.4/topics/auth/#django.contrib.auth.views.login
Try removing the template name from your url configuration. Django will then fall back to a standard template, that way you can see if you screwed up the template somehow or if something else is wrong.
My next guess would be to check your settings for the TEMPLATE_CONTEXT_PROCESSORS. If you have defined any of them, be sure to include
"django.contrib.auth.context_processors.auth",
If you haven't defined any, django will use a standard tuple, which allready includes the auth processor.

How to translate a form in django

I have a form in a django site
<form method="POST" action="." class="right_custom">{% csrf_token %}
<br>{% trans "Enter the discount coupon code if you have any" %}</br>
<input type="text" name="coupon_code" size="25" maxlength="25" />
<input type="submit" name="submit" value="Caluclate Discount"/>
</form>
I would like to translate the entire site to a lot of languages. I need to translate the button text which is Caluclate Discount. How can I do that? if i use {% trans %} tag, how will the view catch the right post request?
UPDATE
There are many forms on the same page like this and my view uses if postdata['submit']=="Caluclate Discount" to determine which submit request it is.
I was able to get the translation working.
Thanks to the answers by #linux-warrior and #Joachim
Now the form is
<form method="POST" action="." class="right_custom">{% csrf_token %}
<input type="hidden" name="form_name" value="discount_form" />
<br>{% trans "Enter the discount coupon code if you have any" %}</br>
<input type="text" name="coupon_code" size="25" maxlength="25" />
<input type="submit" name="submit" value="{% trans "Caluclate Discount" %}" />
</form>
And i check for if postdata['form_name']=='discount_form' in my view
For buttons, you really don't use the value field for anything else than the button text, so it is straightforward to translate:
<input type="submit" name="submit" value="{% trans "Caluclate Discount" %}"/>
I think that you should use {% trans %} for submit "value". I don't understand why would you need that value inside your view. If you want, you can still give your submit input a custom "name" attribute.
Edit. By the way, your
<br>...</br>
thing inside your form appears to be a bug. You will probably want to make it
<p>...</p>
instead. It is also not recommended to use "submit" name for a type="submit" input (taken from http://api.jquery.com/submit/):
Forms and their child elements should not use input names or ids that conflict with properties of a form, such as submit, length, or method. Name conflicts can cause confusing failures. For a complete list of rules and to check your markup for these problems, see DOMLint.
Your view doesn't care about what is the submit button's value, so even if you translate it, your view function will work.

Form not Posting in Django

I'm trying to do some pretty basic form posts with Django, but whenever I try to click on the button to submit the information nothing happens. No errors or messages of any kind show up in terminal or in developer in Chrome. There is no JS on this page just straight html:
<form method="post" action="/">
{% csrf_token %}
<input type="text" id="name" name="name"/>
<input type="text" id="password" name="password"/>
<input type="button" value="Sign Up!"/>
</form>
My view for this page is pretty straightforward as well:
def sign_up(request):
return render_to_response('portal/signup.html', context_instance=RequestContext(request))
I'm really baffled as to what is going on, I've been following this to learn authentication. Everything works but I thought adding a "create user" would be a next step. I can't seem to get any form of any kind to work on other pages as well.
Any help would be great, I'm going crazy!
I think that your problem is that you're using
<input type="button" value="Sign Up!"/>
instead of
<input type="submit" value="Sign Up!"/>
the input submit will send all the form data to the server, the input button won't.
You can learn a little bit more about forms here : http://www.w3schools.com/html/html_forms.asp