Django: included login form reloading when there are errors - django

I'm building a Django app where I show a landing page if there's no user logged in, and I display the login form within that page. I've followed these setup steps to get going, and then I added a context processor so I could display the login form within my landing page view, and I added it to the context_processors list in settings.py.
All of that is working great! I can successfully log someone in, or if I give a wrong password I get the message that the credentials aren't right.
The problem: in the case where I give a wrong password and fail authentication, the website reloads the login form on its own with the message to the user (so the user's going to another page). How I can display the error message from within that same landing page where the form is originally displayed? (Note: I'm using the default Django authentication and haven't done anything yet to define any special behavior)
landing.html:
{% block content %}
Some welcome message!
{% include "registration/login.html"%}
Some other contents
{% endblock content %}
context_processors.py:
def include_login_form(request):
from django.contrib.auth.forms import AuthenticationForm
form = AuthenticationForm()
return {'form': form}
Login.html:
{% extends 'familytree/base.html' %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>Your account doesn't have access to this page. To proceed,
please login with an account that has access.</p>
{% else %}
<p>Please login to see this page.</p>
{% endif %}
{% endif %}
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
<td>Email address: </td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="Log in" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
Forgot password?
{% endblock %}

Related

Django only loads base.html

I'm trying to learn Django and am trying to setup a user login system. My site only shows the base.html contents, and not the contents of login.html. If I remove the extends base.html, the login form seems to show up correctly. Am I doing something wrong?
login.html
{% extends "base.html" %}
{% load url from future %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}
base.html
<body>
<div>
{{ user }}
{% if user.is_anonymous %}
login
{% else %}
logout
{% endif %}
</div>
Your base.html template is missing a corresponding {% block content %}{% endblock content %} and also a closing </body> tag. There's nowhere for the content in login.html to go.
Brandon is right.
you can think {%block content %} as a hole in your base.html and the extended file only replace/fill in that hole.

Login only works for admin

I'm working on a project in Django and trying to use the built in view at
django.contrib.auth.views.login
I have
(r'^accounts/login/$', auth_views.login)
in urls.py
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
in the registration/login.html that django requires to use the login view.
I verified that the user/password combination is correct using the admin page. In the accounts/login page, if I type in my admin username/password it will log me in, but it won't do it for regular users. Why would that be?
you dont use the login function directly as your view function.. and admin page is working because it isnot using your url-mapping.
you need
#views
from django.contrib.auth.views import login
def log_me_in(request):
# todos.. authenticattion...
login(request, user)
and in urls
(r'^log_me_in/$', 'yourapp.views.log_me_in')
it is important not to name your login function the same as login() from auth.. otherwise you get stuck in maximum recursion reached or something like this.. meaning they end up calling each other and go into endless loop..
just read the docs

Django logout_then_login fails to redirect to proper login page

In a Django project, my homepage view is as follows:
#login_required
def home(request):
return render(request, 'home.html')
So that when someone tries to access the homepage, they're automatically taken to a login form if no one is logged in. Here's that form, straight from the Django docs:
{% extends "base.html" %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url django.contrib.auth.views.login %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}
Once someone logs into the form, they get taken to the homepage which looks like this:
{% extends "base.html" %}
{% block content %}
<form method="post" action="{% url django.contrib.auth.views.logout_then_login %}">
{% csrf_token %}
<input type="submit" value="logout" />
</form>
<h1>Home Page</h1>
{% endblock %}
As you can see, I've attempted to create a logout button that will take the user right back to the login page. However, I noticed that when first arriving at the login page, the URL ends in ?next=/, whereas once I "logout", the "login" page I'm taken to has a URL lacking ?next=/. And when I try to login using that page, I'm sent to the URL /accounts/profile/ (instead of the proper homepage URL), which doesn't exist. I'm guessing I've done something wrong in urls.py, but I'm not sure what:
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
(r'^accounts/logout/$', 'django.contrib.auth.views.logout_then_login'),
What am I missing here?
You should tell Django where it should redirect visitors when it doesn't receive a next parameter. This is done with a LOGIN_REDIRECT_URL settings, as explained in the Django documentation.

How to add a button for password request in django login?

In my django App on the login page i want to have a request password button which functions like, when this button is clicked I get a request from the user per email to provide that user a password for the site.At the template login.html I made this change :
{% extends "base.html" %}
{% load url from future %}
{% block site_contents %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" name="request_password" value="Request Password" />
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}
Where in views can I write code to capture the event request_password and write my code to email to the amdin about user's request?
Thanks in advance
I think this would be easier to do by creating a new form and pointing it to your own view. Or, if you want to have it in one form, you can probably create a view along the lines of:
from django.contrib.auth.views login as original_login
def my_login(request):
if request.method == 'POST' and 'request_password' in request.POST:
# process password request somehow
else:
return original_login(request)
Modifying Django-supplied view would probably just complicate things for you in the long run.

login Page by using django forms

I am New beginner in python and django...
i want to know how can i create a login form by using django forms(forms.py)
In your urls.py file link to the built in Django login view, and pass in the path to a template you wish to use as the login page:
(r'^login/$', 'django.contrib.auth.views.login', {
'template_name': 'myapp/login.html'
}),
And here is an example of what the template my look like (from the Django docs):
{% extends "mybase.html" %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}
Yes, you can. Actually, you don't need to create your own form. Simply use auth module and create your own login template. Read this: http://docs.djangoproject.com/en/dev/topics/auth/