Authentication System

Import Django login and logout views from project.

  1. Open urls.py in mysite directory
  • import views: from django.contrib.auth import views as auth_views
  • add login, logout path
from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.urls import path, include
from users import views as user_views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),
    path('register/', user_views.register, name ='register'),
    path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout')
]
  1. Create login and logout templates in users template
├── templates
│   └── users
│       ├── login.html
│       ├── logout.html
│       └── register.html
  1. Edit login template

We can copy the register template and edit certain parts

{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
    <div class="content-section">
        <!-- Sign up form -->
        <form method="POST">
            {% csrf_token %}
            <fieldset class="form-group"> 
                <legend class="border-bottom mb-4">Log in</legend>
                {{ form|crispy }}
            </fieldset>
            <div class="form-group">
                <button class="btn btn-outline-info" type="submit">Login</button>
            </div>
        </form>
        <!-- Sign in form -->
        <div class="border-top pt-3">
            <small class="text-muted">
                Do you need an account? <a class="ml-2" href="{% url 'register' %}">Sign up now</a>
            </small>
        </div>
    </div>
{% endblock content %}
  1. Add login link in register.html tempate
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
    <div class="content-section">
        <!-- Sign up form -->
        <form method="POST">
            {% csrf_token %}
            <fieldset class="form-group"> 
                <legend class="border-bottom mb-4">Join us today</legend>
                {{ form|crispy }}
            </fieldset>
            <div class="form-group">
                <button class="btn btn-outline-info" type="submit">Sign up</button>
            </div>
        </form>
        <!-- Sign in form -->
        <div class="border-top pt-3">
            <small class="text-muted">
                Already have an account? <a class="ml-2" href="{% url 'login' %}">Sign in</a> <!-- Add login link -->
            </small>
        </div>
    </div>
{% endblock content %}
  1. After users can login, we redirect them to our Homepage.

To do that, in mysite/settings.py, we add LOGIN_REDIRECT_URL = 'blog-home' at the bottom of the file.

STATIC_URL = '/static/'

CRISPY_TEMPLATE_PACK = 'bootstrap4'

LOGIN_REDIRECT_URL = 'blog-home'
  1. Update register view in views.py

We should redirect them in the login page after the account is created.

from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm

def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST) 
        if form.is_valid():
            form.save() # Save user to Database
            username = form.cleaned_data.get('username') # Get the username that is submitted
            messages.success(request, f'Your account has been created! You are now able to log in') # Show sucess message when account is created
            return redirect('login') # Redirect user to Login page
    else:
        form = UserRegisterForm()
    return render(request, 'users/register.html', {'form': form})
  1. Add logout template
{% extends "blog/base.html" %}
{% block content %}
    <h2>You have been logged out</h2>
    <div class="border-top pt-3">
        <small class="text-muted">
            <a href="{% url 'login' %}">Log in again</a>
        </small>
    </div>
{% endblock content %}
  1. Create a view for user profile
  • Create users/profile.html template
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
    <h1>{{ user.username }}</h1>
{% endblock content %}
  • In users directory, edit views.py:
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required # Import login_required decorator
from .forms import UserRegisterForm

def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST) 
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'Your account has been created! You are now able to log in')
            return redirect('login')
    else:
        form = UserRegisterForm()
    return render(request, 'users/register.html', {'form': form})

@login_required # Require user logged in before they can access profile page
def profile(request):
    return render(request, 'users/profile.html')
  • Add profile route in urlpattern in mysite.urls.py:
urlpatterns = [
path('profile/', user_views.profile, name='profile')
]
  • Add login route in mysite/settings.py at the end of the file:
STATIC_URL = '/static/'

CRISPY_TEMPLATE_PACK = 'bootstrap4'

LOGIN_REDIRECT_URL = 'blog-home'
LOGIN_URL = 'login'
  1. Update navbar in blog/base.html, so it shows login and register links if user is not logged in, or profile and logout links if user is logged in.
<!-- Navbar Right Side -->
<div class="navbar-nav">
    {% if user.is_authenticated %}
        <a class="nav-item nav-link" href="{% url 'profile' %}">Profile</a>
        <a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a>
    {% else %}
        <a class="nav-item nav-link" href="{% url 'login' %}">Login</a>
        <a class="nav-item nav-link" href="{% url 'register' %}">Register</a>
    {% endif %}
</div>

In the next lesson, we’ll update the profile.html to show user profile and picture.