Setting up user registration was simple, but adding email confirmation to verify users felt like a challenge. Over the years, I’ve built many Django applications for clients across the USA, and one thing is clear: email confirmation is essential for security and user trust.
In this tutorial, I’ll walk you through creating a user registration system in Django that sends an email confirmation link. This ensures users verify their email addresses before fully activating their accounts, a common requirement for professional applications like membership sites, e-commerce platforms, or corporate portals.
Let’s get in!
Why Email Confirmation Matters in User Registration
Email confirmation helps:
- Prevent fake or spam user accounts
- Verify users’ identity and contact info
- Improve security by reducing bot signups
- Enhance user engagement and trust
If you’re building any web app where user identity matters, for example, a local business portal in New York or a membership site for a Chicago-based community, implementing email confirmation is a must.
Check out Python Django “Template does not exist” error
Method 1: Use Django’s Built-in Tools with Custom Token Generator
This method leverages Django’s built-in User model and a custom token generator for email verification. It’s straightforward and highly customizable.
Step 1: Set Up Your Django Project and App
django-admin startproject myproject
cd myproject
python manage.py startapp accountsAdd accounts to your INSTALLED_APPS in myproject/settings.py:
INSTALLED_APPS = [
# other apps,
'accounts',
]Step 2: Configure Email Settings
For development, you can use the console backend to print emails to the terminal:
# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com' # For production, use Gmail SMTP or your provider
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your_email@gmail.com'
EMAIL_HOST_PASSWORD = 'your_email_password'Note: For production, replace the console backend with SMTP settings.
Read Integrity Error in Django
Step 3: Create a Custom Token Generator
Create a file accounts/tokens.py:
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils import six
class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
return (
six.text_type(user.pk) + six.text_type(timestamp) +
six.text_type(user.is_active)
)
account_activation_token = AccountActivationTokenGenerator()Step 4: Create the Registration Form
In accounts/forms.py:
from django import forms
from django.contrib.auth.models import User
class SignUpForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password_confirm = forms.CharField(widget=forms.PasswordInput, label="Confirm Password")
class Meta:
model = User
fields = ('username', 'email', 'password')
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get("password")
password_confirm = cleaned_data.get("password_confirm")
if password and password_confirm and password != password_confirm:
self.add_error('password_confirm', "Passwords do not match")Read Django Programming Error: Column does not exist.
Step 5: Create Views for Registration and Activation
In accounts/views.py:
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_str
from django.contrib.auth import login
from django.http import HttpResponse
from .forms import SignUpForm
from .tokens import account_activation_token
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False # Deactivate account till it is confirmed
user.set_password(form.cleaned_data['password'])
user.save()
current_site = get_current_site(request)
subject = 'Activate Your Django Account'
message = render_to_string('accounts/account_activation_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
})
user.email_user(subject, message)
return HttpResponse('Please confirm your email address to complete the registration.')
else:
form = SignUpForm()
return render(request, 'accounts/signup.html', {'form': form})
def activate(request, uidb64, token):
try:
uid = force_str(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and account_activation_token.check_token(user, token):
user.is_active = True
user.save()
login(request, user)
return HttpResponse('Thank you for your email confirmation. You are now logged in.')
else:
return HttpResponse('Activation link is invalid!')Step 6: Create URL Patterns
In accounts/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('signup/', views.signup, name='signup'),
path('activate/<uidb64>/<token>/', views.activate, name='activate'),
]Include these URLs in your main myproject/urls.py:
from django.urls import path, include
urlpatterns = [
path('accounts/', include('accounts.urls')),
# other paths
]Check out Create a Music Player Application using Django
Step 7: Create Email and Signup Templates
templates/accounts/account_activation_email.html
Hi {{ user.username }},
Please click on the link below to confirm your registration:
http://{{ domain }}{% url 'activate' uidb64=uid token=token %}templates/accounts/signup.html
<h2>Sign Up</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Register</button>
</form>Step 8: Run Your Server and Test
python manage.py migrate
python manage.py runserverVisit http://localhost:8000/accounts/signup/ to test the registration flow.
You can see the output in the screenshot below.




Read Create a Dictionary Application in Django
Method 2: Use Django Allauth for Faster Setup
If you want a more feature-rich, out-of-the-box solution, I recommend using the django-allauth package. It handles registration, login, email verification, social auth, and more.
Quick Setup
pip install django-allauthAdd to settings.py:
INSTALLED_APPS = [
# other apps
'django.contrib.sites',
'allauth',
'allauth.account',
'allauth.socialaccount',
]
SITE_ID = 1
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
)
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_EMAIL_REQUIRED = True
LOGIN_REDIRECT_URL = '/'Add URLs in urls.py:
path('accounts/', include('allauth.urls')),django-allauth automatically sends email confirmation links and manages user activation.
I’ve found that implementing email confirmation in Django not only improves security but also boosts user confidence in your app. Whether you choose the manual approach with a custom token or leverage django-allauth both methods work well in real-world USA-based applications, from local businesses to nationwide services.
Try the first method if you want full control and customization. Use the second if you want a quick, reliable solution with advanced features.
You may read:

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.