Django url parsing error - django

OK,
I have two different views, both in the project site-wide area.
urls.py
url(r'^accounts/login/$', 'taxo.views.login'),
url(r'^accounts/invalid/$', 'taxo.views.invalid'),
...
taxo/views.py
def login(request):
c = {}
c.update(csrf(request))
return render_to_response('login.html', c)
def invalid(request):
return render_to_response('invalid.html',{'title':'invalid'})
templates/login.html
<form action="/accounts/auth/" method="post">{% csrf_token %}
<label for="username">User name</label>
<input type="text" name="username" value="" id="username">
<label for="password">Password</label>
<input type="password" name="password" value="" id="password">
<input type="submit" value="login" />
</form>
templates/invalid.html
<form style="float: right" action="accounts/login/" method="post">
{% csrf_token %}
{{form}}
<input type="submit" value="Login" class="search"/>
</form>
With the above code, I got Page not Found error
Page not found (404)
Request Method: POST
Request URL: http://127.0.0.1:8000/accounts/invalid/accounts/login/
Django parses the requested url as relative to the url of the current page. When I replaced the action with the {% url %} tag. I got a NoReverseMatch at /accounts/invalid/ error
How do I do this correctly?

Try this:
<form style="float: right" action="/accounts/login/" method="post">
{% csrf_token %}
{{form}}
<input type="submit" value="Login" class="search"/>
</form>

And here's the reason:
Request URL: http://127.0.0.1:8000/accounts/invalid/accounts/login/
$ at the end of regex means nothing's after slash:
url(r'^accounts/login/$', 'taxo.views.login', name='login'),
url(r'^accounts/invalid/$', 'taxo.views.invalid', name='invalid'),
therefore you may use those urls:
http://127.0.0.1:8000/accounts/login/
http://127.0.0.1:8000/accounts/invalid/
edit:
why one of your URLs in template redirects begins with slash and one without? Try this one:
<form style="float: right" action="{% url 'login' %}" method="post">

Related

Forbidden (403) CSRF verification failed

When I click on ok button in add_tech.html then it will redirect me on upload_type.html.
But it show error while clicking on ok button.
ERROR -
Forbidden (403)
CSRF verification failed. Request aborted.
Help
Reason given for failure:
CSRF token missing or incorrect.
My template(add_tech.html) -
<form action="/uploads/type/" method="post">
<label for="your_name">New Tech: </label>
<input id="your_name" type="text" name="your_name" value="{{ current_name }}">
<input type="submit" value="OK">
</form>
My Template(upload_type.html)-
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form}}
</form>
My View.py -
def upload_type(request):
if request.method =='POST':
details = NameForm(request.POST)
if details.is_valid():
return render(request, "core/upload_type.html", {'form':details})
else:
details = NameForm()
return render(request, 'core/upload_type.html', {'form': details})
My Url.py -
urlpatterns = [
url(r'^uploads/type/$', views.upload_type, name='upload_type'),]
My form.py -
from uploads.core.models import Name
class NameForm(forms.ModelForm):
class Meta:
model = Name
fields = ('your_name', )
My Models.py-
class Name(models.Model):
your_name = models.CharField(max_length=100)
You need to have the csrf token like this for your post method in the django template
<form action="/uploads/type/" method="post">
{% csrf_token %}
<label for="your_name">New Tech: </label>
<input id="your_name" type="text" name="your_name" value="{{ current_name }}">
<input type="submit" value="OK">
</form>
For POST request, csrf token is required. So in your template, add `{% csrf_token %}.
<form action="/uploads/type/" method="post">
{% csrf_token %}
<label for="your_name">New Tech: </label>
<input id="your_name" type="text" name="your_name" value="{{ current_name }}">
<input type="submit" value="OK">
</form>
From the Docs:
Django ships with an easy-to-use protection against Cross Site Request
Forgeries. When submitting a form via POST with CSRF protection
enabled you must use the csrf_token template tag as in the preceding
example.

Django only submitting csrf token in forms?

So, I have this in my template:
<form action="./validate_code/" method="POST">
{% if error %}
<p>Sorry, that wasn't right.</p>
{% endif %}
<label for="class_code">Your class code: </label>
<input type='text' id='class_code'/>
<input type="color" id="color"/>
{% csrf_token %}
<input type="submit" value="submit">
</form>
Which compiles to:
<form action="./validate_code/" method="POST">
<label for="class_code">Your class code: </label>
<input type='text' id='class_code'/>
<input type="color" id="color"/>
<input type='hidden' name='csrfmiddlewaretoken' value='tGA4jKF1pd1QFC6NSAM9eNFvZqss0r4m' />
<input type="submit" value="submit">
</form>
And when I click submit, firefox sends this parameter:
csrfmiddlewaretoken:"tGA4jKF1pd1QFC6NSAM9eNFvZqs60r4m"
That's it. No text, no color. I have no idea what's going on.
None of your fields have a name attribute, so the browser sends no data.
You should really be using Django's forms framework for this, though.
As mentioned above, you need to specify a "name" attribute in your input fields. You don't need to use Django forms, but if you are submitting the form normally, any fields you are expecting to be sent need to have a name.
<form action="./validate_code/" method="POST">
{% if error %}
<p>Sorry, that wasn't right.</p>
{% endif %}
<label for="class_code">Your class code: </label>
<input type="text" name="class_code" id="class_code">
<input type="color" name="color">
{% csrf_token %}
<button type="submit">Submit</button>
</form>

Django-rest-framework: rewrite default form validaiton

I have recently started to use django-rest-framework in my projects and I have faced a problem.
Here is a simple auth form I have:
<form action="{% url 'rest_framework:login' %}" method="post">
{% csrf_token %}
<input type="e-mail" name="username" value="" placeholder="Логин" maxlength="100" required="required">
<input type="password" name="password" value="" placeholder="Пароль" maxlength="100" required="required">
<button type="submit" class="lightbluebtn">Войти</button>
</form>
I can't really figure out how to validate it. I just need the error to be shown on the form.
Every time I submit my form with invalid data I redirected to rest-framework login page.
Also I have django-rest-framework default urls:
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
Is there any way to use it with django default forms?
Can you guys help me to fix it?
I will be very grateful for the help.
if for the api you are using a session authentication then you don't need the rest_framework login page, that page is useful usually in the dev environment, you can just point to the {% url 'login' %} page (that uses django.contrib.auth.views.login view), and override that template by naming yours registration/login.html , for outputting form errors just use {{ form.error }}, like for example:
{# file registration/login.html #}
{% if form.errors %}
<div class="alert alert-danger">
<p>Your email and password didn't match. Please try again.</p>
</div>
{% endif %}
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
<input type="e-mail" name="username" value="" placeholder="Логин" maxlength="100" required="required">
<input type="password" name="password" value="" placeholder="Пароль" maxlength="100" required="required">
<button type="submit" class="lightbluebtn">Войти</button>
</form>

Django registration and password reset on one page

Is there way to create just one page for login and reset password?
I tried to create two forms page with following code in template:
<form action="" method="post" id="formLoginIndex">
{% csrf_token %}
<div id="elogin">
<p><label for="id_username">Login</label>
{{ form.username }}</p>
<p><label for="id_password">Пароль</label>
{{ form.password }}</p>
</div>
<p class="submit">
<button type="submit" class="enter">Enter</button>
{% if next %}
<input type="hidden" name="next" value="{{ next }}" />
{% else %}
<input type="hidden" name="next" value="/electricity/" />
{% endif %}
<button class="forgot" type="button" onclick="$('#forgotten').toggle('normal');">Forgot password?</button>
</p>
</form>
<div id="forgotten">
<form action="/reset/done/" method="post" id="formForgot">
{% csrf_token %}
<p>
<label for="id_username_forgot">Login</label>
<input id="id_username_forgot" type="text" name="username" maxlength="30" />
</p>
<p>
<label for="id_email">e-mail</label>
<input id="id_email" type="text" name="email" maxlength="40" />
</p>
<p class="submit">
<button class="remember" type="submit">Reset</button>
</p>
</form>
</div>
And urls :
url(r'^login/$', 'django.contrib.auth.views.login'),
url(r'^reset/done/$', 'django.contrib.auth.views.password_reset_done'),
However works only login feature. Reset doesn't work. Obviously is that I'm just doing smth wrong.
So should I load somehow views.password_reset into the same page or even rewrite django in auth views or there is another common solution?
The point is that you need a form to show the PasswordResetForm and it's action should be set to point to reset/
when this form is submitted via method POST, it's redirected to where the argument post_change_redirect points to, and there you can show the user that the password has been changed.
( In case the form evaluates to be correct , else, it would re-render the form with errors shown )
url(r'^reset/$', password_reset,
{'template_name':'your_template',
'post_change_redirect':'/reset/done/',
'extra_context':{'argument':'to tempate'}}, name='some_name'),
url(r'^reset/done/', password_reset_done,
{'template_name':'the template to show a success message',
'extra_context':{'message':'your password is changed successfully'}},),
looking at the defaults for this function ,It gives some cool info about how it works and its defaults if not given:
password_reset (request, is_admin_site=False,
template_name='registration/password_reset_form.html',
email_template_name='registration/password_reset_email.html',
subject_template_name='registration/password_reset_subject.txt',
password_reset_form=PasswordResetForm,
token_generator=default_token_generator,
post_reset_redirect=None,
from_email=None,
current_app=None,
extra_context=None)

Add an additional form with django-registration

I have a registration form that is rendered by the following urlconf --
url(r'^$',
register,
{'backend': 'registration.backends.default.UserBackend',
'template_name': 'index.html'},
name='auth_index'),
In the template, I have the following --
<form method="post" action=".">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Register" />
</form>
How would I add additional forms and context to this template? I want to be able to have something like the following --
<form method="post" action=".">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Register" />
</form>
...
<form action='{% url waiting_list %}' method='post'>{% csrf_token %}
<p>Enter your email: <input type="text" name="email" value=""></p>
<input type="submit" name="email_submit" value="Submit Email">
</form>
{{message}}
How could I do this? (Preferably, all within a view). Thank you.
Your template is OK. Now you add the waiting_list url to your uelconf and implement it's view:
url(r'^waiting_list/$', 'myapp.views.waiting_list', {}, name='waiting_list'),
and:
# myapp/views.py
def waiting_list(request):
...
Since this is not data critical form, I would probably use #csrf_exempt to bypass csrf validation to makes thing easier. In case of error, redirect to an error page.
(BTW, usability wise, a better implementation for this problem might be posting the email with javascript.)