Django default authentication supports username and password only. In this tutorial we will setup email authentication which will enable us to login with email and password instead of username.
Since we will be creating our own custom User model, this tutorial is helpful only when you are creating a new project.
Authentication is process by which we identify the users and give them access to specific sections in our websites. In this tutorial, we will also attach specific attributes to users in our website to identify if they are staff users, normal users or administrators.
Common authentication methods used in websites and mobile apps are:
- Email Authentication (email and password)
- Email Authentication with Magic link
- Social signin (login with facebook, google and others)
- Login with mobile phone and OTP
We will cover the first authentication method (Email Authentication) where users will enter email and password to login to our website.
Disclaimer: This tutorial includes best practices and approaches necessary when working in any production grade project. This may seem complicated and unnecessary for beginners. I will try to explain all these points below.
Installing specific python version
It is best practice to pin our project to a specific python version. As we add dependencies and new code in our project, we might encounter issues when the project automatically picks the latest python version. With each version new of python new features are added and sometimes old features are removed or deprecated.
If we specify only python3 as the requirement, the developers could install python3.6, python3.7, python3.8, python3.9, python3.10 or python3.11. When multiple developers are working with multiple python versions, the code changes might become incompatible between python versions.
To fix this, we specify a specific python version and every developer uses the same version. Since multiple projects can have different python version requirement, we need a way to install multiple python versions in our machine.
We are using pyenv for creating specific python version (e.g. python 3.8.0 for this project). More details on using pyenv
We first create the base directory which will contain all our code
django-email-auth we will configure specific python version.
This will create
.python-version file in this directory (
django-email-auth). Let's verify that our local python installation is working correctly.
Now, we have configured a specific python version, the next step would be to configure virtual environment.
Creating virtual environment
We will create virtual environment before setting up the project. As per 12 Factor App dependencies should be declared explicitly. We will make sure every dependency of the project is pinned to specific version (including python too). Virtual environment helps us to separate system level python and it's packages with our project specific packages.
Make sure we are in
django-email-auth directory where we setup python 3.8.0. We are using python inbuilt feature to create a virtual environment in
After setting up the virtual environment, we will upgrade pip to specific version
Since we are using virtual environemnt, this gets installed in
We will add this specific Django version to a text file so that other developers working on the project know the specific version that we are using. For this, we generally create a requirements.txt file which specifies all the packages and their specific version. All these dependencies can be installed later by using
pip install -r requirements.txt
Let's create a new
requirements.txt file in
django-email-auth and add below content.
Creating demo project
Since we have already created the directory,
django-email-auth, we will create a new project and specify
. so that it doesn't create nested directory
Below is the directory structure created
. ├── manage.py ├── project │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── requirements.txt └── venv ├── bin ├── include ├── lib └── pyvenv.cfg
We will be creating all our custom apps inside a specific directory
django-email-auth. This will help us to organized our project files in a cleaner way. This approach is optional.
Creating custom User model for email instead of username
We will create a new app
custom_auth and a model
mkdir -p apps/custom_auth venv/bin/django-admin startapp custom_auth apps/custom_auth
Since we have created app inside apps directory, will have to update
apps/custom_auth/apps.py and change
name = 'custom_auth' to
name = 'apps.custom_auth'
We will add this new app to our settings file at
INSTALLED_APPS in this file and append below code.
# project/settings.py -> INSTALLED_APPS 'apps.custom_auth.apps.CustomAuthConfig'
We create a new user by extending
- we are adding PermissionsMixin as this will provide us out of the box django group and permissions functionality
- is_staff is to identify users who can login to django admin backend
- PermissionsMixin provides is_superuser field which enables admin account. This account will have all the permissions on all models in django
Add below code in
custom_auth/models.py. Below code contains both
User model and
Add below code in
custom_auth/admin.py. This will enable admin functionality for the
User model which we created earlier.
Since we have create our own
User model, we will have to configure Django to use our model instead of the default
User model. For this, we add below configuration in
# append below code at the end of file project/settings.py AUTH_USER_MODEL = 'custom_auth.User'
User model is configured. Now we create migrations.
venv/bin/python manage.py makemigrations custom_auth
Applying all migrations along with the new
venv/bin/python manage.py migrate
Create a super user which we will use for login.
venv/bin/python manage.py createsuperuser
Run server and access http://localhost:8000/admin/ to verify
venv/bin/python manage.py runserver
After login, we can access the admin console for
User model http://localhost:8000/admin/custom_auth/user/ and create new users.