Chapter 19 User Accounts (II)
Create user accounts
In this section, we will create a user registration and authentication system.
Application users
First use the command Python management. py startapp users to create an application named users. Now your directory should be the same as the following.
1. Add application users to settings.py
#--snip-- INSTALLED_APPS = ( #--snip-- 'learning_logs', 'users', ) #--snip--
2. Create the URL schema for users
from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^users/', include('users.urls', namespace='users')), url(r'', include('learning_logs.urls', namespace='learning_logs')), ]
The added code matches any URL headed by the word users (such as http://localhost:8000/users/login/).
Login page
Create a new urls.py in learning_log/users/.
from django.conf.urls import url from django.contrib.auth.views import login from . import views urlpatterns = [ url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'), ]
First import the default view login, and then the URL mode of the login page matches the URL http://localhost:8000/users/login/. The argument login (not views.login) tells django to send the request to view login. A dictionary specifies the template to be looked up.
1. Template login.html
Similarly, create a new path users/templates/users /, and then create a new login.html under that path.
{% extends "learning_logs/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 'users:login' %}"> {% csrf_token %} {{ form.as_p }} <button name="submit">log in</button> <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" /> </form> {% endblock content %}
This template also inherits base.html. Templates in one application can inherit templates in another application.
The form errors attribute displays an error message when a username-password error is entered.
Set the argument action to the URL of the login page and let the login view process the form. The form element next tells django to redirect the user to the home page after successful login.
2. Link to login page
Add a link to the login page in base.html, but when the user is logged in, in order not to display the link, we nest it in the {% if%} tag.
<p> <a href="{% url 'learning_logs:index' %}">Learning Log</a> - <a href="{% url 'learning_logs:topics' %}">Topics</a> - {% if user.is_authenticated %} Hello, {{ user.username }}. {% else %} <a href="{% url 'users:login' %}">log in</a> {% endif %} </p> {% block content %}{% endblock content %}
In django authentication system, each template can use the variable user, the variable is_authenticated attribute: if the user has logged in, the attribute value is True, otherwise it is Faule; the variable's username attribute is user name.
3. Use login pages
If you have logged in to an administrator before, remember to log out at http://127.0.0.1:8000/admin. Then re-login to our Learning Notes page at http://127.0.0.1:8000/users/login/, and use the administrator's password to login.
Cancellation
1. write off URL
#users/urls.py from django.conf.urls import url from django.contrib.auth.views import login from . import views urlpatterns = [ url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'), url(r'^logout/$', views.logout_view, name='logout'), ]
2. View function logout_view()
django has its own function module logout(), we just need to import it and call it to redirect to the home page.
from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from django.contrib.auth import logout def logout_view(request): logout(request) return HttpResponseRedirect(reverse('learning_logs:index'))
Here, the request object is passed as an argument to the function logout().
3. Link to logout view
Add a logout link to base.html. To make the user visible only after he logs in, we put him in the label {% if user.is_authenticated%}.
#base.html <p> <a href="{% url 'learning_logs:index' %}">Learning Log</a> - <a href="{% url 'learning_logs:topics' %}">Topics</a> - {% if user.is_authenticated %} Hello, {{ user.username }}. <a href="{% url 'users:logout' %}">log out</a> {% else %} <a href="{% url 'users:login' %}">log in</a> {% endif %} </p> {% block content %}{% endblock content %}
Run the server as you can see
Registration page
1. The URL mode of the registration page
from django.conf.urls import url from django.contrib.auth.views import login from . import views urlpatterns = [ url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'), url(r'^logout/$', views.logout_view, name='logout'), url(r'^register/$', views.register, name='register'), ]
2. View function reigster()
When the registration page is first requested, the view function register() displays an empty registration form. After the user submits the registration, the registration is successful and automatically logs in.
from django.shortcuts import render from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from django.contrib.auth import login, logout, authenticate from django.contrib.auth.forms import UserCreationForm def logout_view(request): --snip-- def register(request): if request.method != 'POST': #Display empty registration form form = UserCreationForm(); else: #Handle completed forms form = UserCreationForm(data=request.POST) if form.is_valid(): new_user = form.save() #Allow users to log in automatically and redirect to the home page authenticate_user = authenticate(username=new_user.username, password=request.POST['password1']) login(request, authenticate_user) return HttpResponseRedirect(reverse('learning_logs:index')) context = {'form': form} return render(request, 'users/register.html', context)
Functions login() and authenticate() allow users to login automatically after successful registration.
When registering, if the registration form data submitted by the user is valid, call method save() and return the newly created user object, which is saved in new_user.
During the automatic login process, we call authenticate() and pass the argument new_user.username and password (because the form is valid and the two passwords are the same, so we use the first password'password1') to it. Then we save the authenticated user object returned by authenticate() in authenticate_user. Finally, the function login() is called and the object request and authenticate_user are passed to him. Finally, the automatic login is completed.
3. Registration Template
Create a register.html and put it together with login.html.
{% extends "learning_logs/base.html" %} {% block content %} <form method="post" action="{% url 'users:register' %}"> {% csrf_token %} {{ form.as_p }} <button name="submit">register</button> <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" /> </form> {% endblock content %}
4. Link to the registration page
<p> <a href="{% url 'learning_logs:index' %}">Learning Log</a> - <a href="{% url 'learning_logs:topics' %}">Topics</a> - {% if user.is_authenticated %} Hello, {{ user.username }}. <a href="{% url 'users:logout' %}">log out</a> {% else %} <a href="{% url 'users:register' %}">register</a> - <a href="{% url 'users:login' %}">log in</a> {% endif %} </p> {% block content %}{% endblock content %}
Run the server as you can see