In this tutorial, you’ll learn how to create a Registration Form for User Signup. We’ll add more functionality by adding validation and sending a confirmation link on users’ email. With confirming account user cannot sign in. You can also find this tutorial code on GitHub. Django registration with confirmation email. Django-registration send activation email. Learn how to send confirmation emails to users after form submission.
For example, we will be using the project in which we have created previously a login/logout and password reset/change view. For this tutorial, I have created an app named core.
Here you will be learning the following example –
How to Create User Registeration in Django
How to Update Profile of Registered Users in Django
Let’s get started.
For the testing purpose, I will be using Email Console which prints email in the terminal instead of sending an email.
settings.py
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
Sign up with Django Email Confirmation
Create a model named Profile in models.py for determinant if the e-mail is confirmed or not. . We will additionally add a Django signal bellow the model. A new entry is added within the User model, the signal is going to be trigger and add details in Profile model with default django email confirm as false.
models.py
from django.db import models from django.contrib.auth.models import User from django.db.models.signals import post_save from django.dispatch import receiver class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) email_confirmed = models.BooleanField(default=False) @receiver(post_save, sender=User) def update_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) instance.profile.save()
Django has internal APIs for creating One Time Link with user details. PasswordResetTokenGenerator API is used for generating token. We will extend PasswordResetTokenGenerator with our class to generate a unique token. This will make use of your SECRET_KEY of your project.
Create a module tokens.py in your app. For example core.
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.profile.email_confirmed) ) account_activation_token = AccountActivationTokenGenerator()
Now let’s create forms.py. We will extend form with UserCreationForm.
forms.py
from django import forms from django.contrib.auth.models import User from django.contrib.auth.forms import UserCreationForm # Sign Up Form class SignUpForm(UserCreationForm): first_name = forms.CharField(max_length=30, required=False, help_text='Optional') last_name = forms.CharField(max_length=30, required=False, help_text='Optional') email = forms.EmailField(max_length=254, help_text='Enter a valid email address') class Meta: model = User fields = [ 'username', 'first_name', 'last_name', 'email', 'password1', 'password2', ]
In views.py, we will create a view SignUpView which will send account activation details on email.
views.py
from django.shortcuts import render, redirect from django.urls import reverse_lazy from django.views.generic import View, UpdateView from core.forms import SignUpForm from django.contrib.auth.models import User from django.contrib import messages from django.contrib.sites.shortcuts import get_current_site from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode from django.template.loader import render_to_string from core.tokens import account_activation_token # Sign Up View class SignUpView(View): form_class = SignUpForm template_name = 'commons/signup.html' def get(self, request, *args, **kwargs): form = self.form_class() return render(request, self.template_name, {'form': form}) def post(self, request, *args, **kwargs): form = self.form_class(request.POST) if form.is_valid(): user = form.save(commit=False) user.is_active = False # Deactivate account till it is confirmed user.save() current_site = get_current_site(request) subject = 'Activate Your MySite Account' message = render_to_string('emails/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) messages.success(request, ('Please Confirm your email to complete registration.')) return redirect('login') return render(request, self.template_name, {'form': form})
Notice in the above code, I am setting user.is_active = False
. This will prevent the user from login until the user email is confirmed.
For sending email we need email template.
account_activation_email.html
{% autoescape off %} Hi {{ user.username }}, Please click on the link below to confirm your registration: http://{{ domain }}{% url 'activate' uidb64=uid token=token %} {% endautoescape %}
signup.html
{% extends 'base.html' %} {% block title %}Sign Page{% endblock title %} {% block content %} <h2>Sign Page</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Register</button> <br><br> <a href="{% url 'home' %}">Home</a> </form> {% endblock content %}
And here are the routes you will need –
urls.py
from django.urls import path from core.views import SignUpView, ActivateAccount urlpatterns = [ path('signup/', SignUpView.as_view(), name='signup'), path('activate/<uidb64>/<token>/', ActivateAccount.as_view(), name='activate'), ]
Note – You have not created ActivateAccount View yet. If you try to runserver it will give an error.
Here far it will look like this –



By clicking on the link in email, the user will be sent to ActivateAccount View.
views.py
from django.contrib.auth import login from django.contrib.auth.models import User from django.utils.encoding import force_text from django.utils.http import urlsafe_base64_decode from core.tokens import account_activation_token class ActivateAccount(View): def get(self, request, uidb64, token, *args, **kwargs): try: uid = force_text(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.profile.email_confirmed = True user.save() login(request, user) messages.success(request, ('Your account have been confirmed.')) return redirect('home') else: messages.warning(request, ('The confirmation link was invalid, possibly because it has already been used.')) return redirect('home')
Here is the logic after registration. The ActivateAccount view will check – if the user exists if the token is valid. If everything is valid and check, then we will set user.is_active = True
and user.profile.email_confirmed = True
and log in the user.

GitHub – Run Example Locally
Code is also available on GitHub – https://github.com/studygyaan/How-to-Signup-User-and-Send-Confirmation-Email-in-Django.git
Clone the Repository
git clone https://github.com/studygyaan/How-to-Signup-User-and-Send-Confirmation-Email-in-Django.git
Change Directory
cd How-to-Signup-User-and-Send-Confirmation-Email-in-Django
Create Virtual Environment – VirtualENV
virtualenv env
Activate Virtual Environment
source env/bin/activate
Run requirements file to install libraries using Pip3
pip3 install -r requirements.txt
Run the server
python3 manage.py runserver
And open http://localhost:8000/ in your browser.