User System — Register, Login, Logout

In this chapter, you will learn to use Django's built-in authentication system to implement user registration, login, and logout functionality.


Django's built-in auth system

Django comes with a complete user authentication module:

  • Built-inUserModels (username, password, email, etc.)
  • Built-in login/logout views (no need to write logic yourself)
  • Built-in permissions and group management
  • Form validation and security protection (CSRF, XSS)

This module isdjango.contrib.authIt is registered in INSTALLED_APPS by default when the project is created.


Registration Page

Django has built-in login/logout views, but no built-in registration view, so we need to write it ourselves.

Step 1: Create Registration Form

Example

# File path: blog/forms.py (new file)
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User

class RegisterForm(UserCreationForm):
    Custom registration form: inherit UserCreationForm, add email field
    email = forms.EmailField(
        label=Email,
        required=True,
        help_text=Please enter a valid email address.
    )

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']
        labels = {
            'username': Username,
        }

Step 2: Write Registration View

Example

# File path: blog/views.py (newly added)
from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.contrib import messages
from .forms import RegisterForm

def register(request):
    """User registration view"""
    # If the user is already logged in, redirect directly to the homepage.
    if request.user.is_authenticated:
        return redirect('index')

    if request.method == 'POST':
        # User submitted the registration form
        form = RegisterForm(request.POST)
        if form.is_valid():
            user = form.save()              # Save user to database
            login(request, user)            # Automatically log in after registration
            messages.success(request, fRegistration successful, welcome, {user.username}!)
            return redirect('index')
    else:
        # GET Request: Displays a Blank Registration Form
        form = RegisterForm()

    return render(request, 'blog/register.html', {
        'form': form,
        'title': 'Register - EXAMPLE Blog'
    })

Django'smessagesThis framework is used to pass one-time messages between requests (such as "Registration successful"). By rendering the messages area in the template, users can see operation feedback. It works with session, and the message disappears automatically after being displayed once.


Login and Logout

Django has built-in login and logout views; you just need to include them in the URL configuration.

Example

# File path: blog/urls.py
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('post/<int:pk>/', views.post_detail, name='post_detail'),
    path('register/', views.register, name='register'),

    # Django built-in login view
    # template_name: specifies which template to use
    path('login/', auth_views.LoginView.as_view(
        template_name='blog/login.html',
        redirect_authenticated_user=True  # Logged-in users who visit login are redirected directly.
    ), name='login'),

    # Django built-in logout view
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]

Configure the redirect addresses for login and logout in settings.py:

Example

# File path: add at the end of blog_project/settings.py
LOGIN_URL = 'login'                    # Unauthenticated users accessing protected pages are redirected to the login page.
LOGIN_REDIRECT_URL = 'index'           # Redirect to the homepage after successful login
LOGOUT_REDIRECT_URL = 'index'          # Redirect to homepage after logout

Create Authentication-related Templates

Login Template

Example

<!-- File path: blog/templates/blog/login.html -->
{% extends 'blog/base.html' %}

{% block title %}Login - EXAMPLE Blog{% endblock %}

{% block content %}
<div class="auth-form">
    <h2>Log in</h2>
    <form method="post">
        {% csrf_token %}
        <div class="form-group">
            <label>Username</label>
            {{ form.username }}
        </div>
        <div class="form-group">
            <label>Password</label>
            {{ form.password }}
        </div>
        {% if form.errors %}
            <p class="error-msg">Incorrect username or password, please try again.</p>
        {% endif %}
        <button type="submit" class="btn-submit">Log in</button>
    </form>
    <p class="form-footer">
No account yet?<a href="{% url 'register' %}">Register now</a>
    </p>
</div>
{% endblock %}

Registration Template

Example

<!-- File path: blog/templates/blog/register.html -->
{% extends 'blog/base.html' %}

{% block title %}Register - EXAMPLE Blog{% endblock %}

{% block content %}
<div class="auth-form">
    <h2>Register</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="btn-submit">Register</button>
    </form>
    <p class="form-footer">
Already have an account?<a href="{% url 'login' %}">Login now</a>
    </p>
</div>
{% endblock %}

{% csrf_token %}This is Django's security mechanism to prevent cross-site request forgery attacks. Any POST form must include it, otherwise Django will reject the request (403 error). This tag generates a hidden input containing a random CSRF token.


Display Login Status in Navigation Bar

Update the navigation bar in base.html to display different content based on login status.

Example

<!-- Modify the navigation bar section of blog/templates/blog/base.html -->
<header class="navbar">
    <a href="/" class="logo">EXAMPLE Blog</a>
    <nav>
        <a href="/">Home</a>

        {% if user.is_authenticated %}
{# Logged in: display username and logout button (user is automatically injected by Django) #}
            <span class="user-name">{{ user.username }}</span>
            <a href="{% url 'logout' %}">Logout</a>
        {% else %}
{# Not logged in: show login and registration links #}
            <a href="{% url 'login' %}">Log in</a>
            <a href="{% url 'register' %}">Register</a>
        {% endif %}
    </nav>
</header>

Django's template context processor will automatically{{ user }}inject it into every template without needing to pass it manually in views.py. You can useuser.is_authenticatedDetermine whether the user is logged in.


Login Page Styling

Example

/* Append to the style in base.html */
.auth-form {
    max-width: 400px;
    margin: 40px auto;
    padding: 30px;
    background: #fff;
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}

.auth-form h2 {
    margin-bottom: 24px;
    text-align: center;
}

.auth-form .form-group {
    margin-bottom: 16px;
}

.auth-form label {
    display: block;
    margin-bottom: 6px;
    font-weight: 500;
}

.auth-form input {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid #ddd;
    border-radius: 6px;
    font-size: 14px;
}

.btn-submit {
    width: 100%;
    padding: 12px;
    background: #2c3e50;
    color: #fff;
    border: none;
    border-radius: 6px;
    font-size: 16px;
    cursor: pointer;
    margin-top: 10px;
}

.error-msg {
    color: #e74c3c;
    font-size: 14px;
}

.form-footer {
    margin-top: 16px;
    text-align: center;
    font-size: 14px;
}

.user-name {
    color: #2c3e50;
    font-weight: 500;
}

Chapter summary

In this chapter, you integrated Django's built-in authentication system: inherited UserCreationForm to create the registration form, used LoginView/LogoutView to implement login/logout, used csrf_token to protect POST requests, and used user.is_authenticated in templates to check login status.

Now the blog has a complete user registration, login, and logout flow.

other extensions