User Registration
The previous lesson leaned on LoginView and LogoutView — both handed to
you, ready-made, by django.contrib.auth. A sign-up page is different: Django
deliberately does not ship a built-in registration view. That's not an oversight
— every project asks for different things at sign-up (some want just a username and password,
others want an email, a display name, terms-of-service acceptance, or more) and Django's
maintainers chose not to guess which shape yours needs. What it does give you is
UserCreationForm, a ready-made ModelForm for the User model,
which is normally enough to build a working sign-up view in a few lines.
A Registration View with UserCreationForm
UserCreationForm already validates a username, checks the two password fields match,
and hashes the password correctly before saving — all of the tricky, security-sensitive parts are
handled. The view around it follows the exact same GET/POST shape as any other form-driven view:
# taskflow/views.py
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
return redirect('login')
else:
form = UserCreationForm()
return render(request, 'registration/register.html', {'form': form})
form.save() here creates a genuine new row in the User table, with the
password already hashed — never the raw text the visitor typed. As written, a freshly registered
visitor lands on the login page and has to sign in separately, which works, but is one extra step
most apps skip.
Logging the New User In Immediately
Django's login() function starts a session for a given user directly, without
requiring a fresh username/password check — exactly what's needed right after registration, since
the visitor just proved who they are by successfully creating the account. Calling it turns the
view above into a true "register and land inside the app" flow:
# taskflow/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.contrib.auth.forms import UserCreationForm
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
login(request, new_user)
return redirect('task-list')
else:
form = UserCreationForm()
return render(request, 'registration/register.html', {'form': form})
After this, request.user on the very next request is the newly created account —
the same request.user concept covered in
User Authentication, now populated the moment sign-up
finishes rather than requiring a separate login step.
UserCreationForm's Default Fields Are Minimal
Out of the box, UserCreationForm only asks for a username and a password (entered
twice, to catch typos). Most real apps want at least an email address too, and the standard way
to add that is subclassing the form rather than rebuilding it from scratch:
# taskflow/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class TaskFlowRegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta(UserCreationForm.Meta):
model = User
fields = ['username', 'email', 'password1', 'password2']
Swapping this form into the register view above needs no other changes — the same
form.is_valid() / form.save() / login() sequence works
identically, now collecting an email address along with the username and password.
Password Validation Happens Automatically
Every password submitted through UserCreationForm is checked against Django's
AUTH_PASSWORD_VALIDATORS setting — a list of validator classes that reject things
like an overly short password, a password too close to the username, or one of the most commonly
used passwords, before the account is ever created. This runs automatically as part of
form.is_valid(); there's nothing extra to call. It's enough, at this stage, just to
know it's there and where it lives in settings.py if the rules ever need adjusting.
When You Need More: django-allauth
The registration flow built above covers the common case well, but real products often need more:
email verification links, password reset flows with extra polish, or "Sign in with Google /
GitHub" buttons. Rather than building all of that by hand, most Django projects that need it reach
for a third-party package — django-allauth being the most widely used — which handles
registration, email verification, and social login as a packaged, configurable add-on. It's worth
knowing this exists once TaskFlow's needs grow past the basics, though it's a large enough topic to
deserve its own dedicated reading outside this track.
django.contrib.auth's built-in User model
covers a lot, but it can't be extended with new fields directly — that requires swapping in a
Custom User Model, next.