March 8, 2023
Login user account with e-mail address
March 8, 2023
One popular solution to these problems is to use an e-mail address as a unique identifier for logins. E-mail addresses are not only unique for each person, but also easier to remember. In addition, most users are already accustomed to using e-mail addresses as identifiers for various online services. Introducing e-mail address-based logins can contribute to users' convenience and satisfaction with applications.
In this article, we will show how to implement email address-based login in a Django application using AbstractUser and function-based views. We'll walk through the process of creating a user model, forms, views, and HTML templates using Bootstrap.
Creating a user model with AbstractUser
In order to implement email address login, we first need to create a custom user model that extends the built-in AbstractUser model. AbstractUser contains all the basic fields and methods necessary to manage user accounts. We will modify this model to use the email address as the primary identifier.
Here is how to build a custom user model:
# accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
username = None
email = models.EmailField(unique=True, blank=False, error_messages={'unique': "A user with that email already exists!"})
account_type = models.CharField(choices=ACCOUNT_TYPE, max_length=10)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
In the above code:
1. We import AbstractUser
from django.contrib.auth.models and models from django.db.
2. we create a new CustomUser
class that inherits from AbstractUser
.
3. we override the email field in the CustomUser
class by adding the unique=True
attribute. This means that each email address must be unique for each user.
4. We set USERNAME_FIELD
to 'email', which means that the email address will be used as an identifier when logging in.
5. We override the '__str__
' method to return the user's email address
Now we need to update the application settings to use our custom user model:
# settings.py
AUTH_USER_MODEL = 'accounts.CustomUser'
In the code above, we replace 'accounts' with the name of the application that hosts the CustomUser
model. AUTH_USER_MODEL tells Django that we want to use our custom user model instead of the default one.
In order for the CustomUser
model to work properly, you will need the CustomUserManager
, which is already included with the user model. Here is the code responsible for this functionality:
# accounts/managers.py
from django.contrib.auth.base_user import BaseUserManager
class CustomUserManager(BaseUserManager):
"""
Custom user model manager where email is the unique identifiers
for authentication instead of usernames.
"""
def create_user(self, email, password, **extra_fields):
"""
Create and save a User with the given email and password.
"""
if not email:
raise ValueError('The Email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
"""
Create and save a SuperUser with the given email and password.
"""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self.create_user(email, password, **extra_fields)
Create forms for registration and login
Next, we need to create forms that will allow users to register and log in using their email address. To do this, we will create two forms: UserRegisterForm
and EmailLoginForm
. We create a new file named forms.py in the folder of our application and add the following code:
# accounts/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import get_user_model
User = get_user_model()
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
class EmailLoginForm(AuthenticationForm):
username = None
email = forms.EmailField()
class Meta:
model = User
fields = ['email', 'password']
In the above code:
1. We import forms from django, UserCreationForm
and AuthenticationForm
from django.contrib.auth.forms and get_user_model
from django.contrib.auth.
2. We retrieve a custom user model using the get_user_model
function and assign it to the User
variable.
3. we create a UserRegisterForm
class that inherits from UserCreationForm
. We add the email field as a required field to the form.
4. In the Meta class of UserRegisterForm
, we set the model to our custom user model and define the list of fields to be included in the form.
5. we create the EmailLoginForm
class, which inherits from AuthenticationForm
. We set username to None, since we will use email address instead of username. We add the email field as a required field to the form.
6. In the EmailLoginForm
Metaform class, we set the model to our custom user model and define the list of fields to be included in the form.
7. Now we have ready forms that will allow users to register and log in using their email address.
Implementation of views for registration and login
Now that we have the forms ready, we can create views that handle the registration and login process. To do this, we add the following code to the views.py
file in our application folder:
# accounts/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from .forms import UserRegisterForm, EmailLoginForm
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
user = form.save()
messages.success(request, 'Konto zostało utworzone! Możesz się teraz zalogować.')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'register.html', {'form': form})
def user_login(request):
if request.method == 'POST':
form = EmailLoginForm(request, request.POST)
if form.is_valid():
email = form.cleaned_data.get('email')
password = form.cleaned_data.get('password')
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
form = EmailLoginForm(request)
return render(request, 'login.html', {'form': form})
def home(request):
return render(request, 'home.html')
In the above code:
1. We import render
, redirect
functions from django.shortcuts module, login
and authenticate
functions from django.contrib.auth, UserRegisterForm
and EmailLoginForm
forms from forms.py
file.
2. We create a register
view function that handles POST and GET requests. If the request is POST, we create an instance of the UserRegisterForm
form with the data submitted by the user. If the form is valid, we save the new user and display a success message, then redirect the user to the login page. If the request is GET, we display a blank registration form.
3. We create a user_login
view function that handles POST and GET requests. If the request is POST, we create an instance of the EmailLoginForm
form with the data submitted by the user. If the form is valid, we attempt to authenticate the user using the authenticate function and pass in the email address and password. If the authentication is successful, we log the user in, display a welcome message and redirect the user to the home page. If the request is GET, we display a blank login form.
4. We create a home
view function to which users will be redirected after they have successfully logged into the application. In a real-world solution, it can definitely be expanded more, but in this example it will only be used to confirm whether the login was successful.
Having the views ready, we can move on to creating HTML templates.
Creating HTML templates using Bootstrap
In this subsection, we'll look at creating HTML templates for our registration and login views using Bootstrap to quickly and easily create attractive and responsive forms. First, we'll create a templates folder in our application's folder, with two files in it: register.html
, login.html
and home.html
.
Let's start with the register.html
template:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rejestracja</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h2>Registration</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">register</button>
</form>
</div>
</body>
</html>
In the above template:
1.We load the static
tag at the beginning of the file to be able to use static files (however, this is not used in this particular template).
2.We add a basic HTML5 structure with meta tags, a title tag and a link to the Bootstrap stylesheet.
3. we create a container in which we place the registration form. The form uses the POST method, and the csrf_token
tag provides security against CSRF attacks.
4. We display the form using {{ form.as_p }}
, which will generate a form with the fields contained inside the <p> tags.
5. We add a "Register" button with Bootstrap class "btn btn-primary".
Now let's go to the login.html
template:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Log in</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h2>Log in</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">Log in</button>
</form>
</div>
</body>
</html>
The login.html
template is very similar to register.html
. The differences are changing the title to "Login" and the button to "Login".
Finally, the home.html
template, after successful login, users will be redirected to it.
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rejestracja</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Successful login!</h1>
<h2>you are now logged in based on your email address</h2>
</div>
</body>
</html>
With the templates ready, we can now add the appropriate URLs to integrate our views with the rest of the application. To do this, we edit the urls.py
file in our application's folder, adding the following paths:
from django.urls import path
from . import views
urlpatterns = [
path('register/', views.register, name='register'),
path('login/', views.user_login, name='login'),
path('home/', views.home, name='home'),
]
In the above code:
1. We import path from the django.urls module and views
from our application.
2. We add paths for the register
, user_login
and home
views, assigning them appropriate names.
In this way, we have integrated our registration and login views into the Django application. Now users can register and log in using their email address.
Example of user registration and login
In this part of the post, we will show how the user registration and login process looks like in our Django application. Recall that we have implemented registration and login functions that use an email address instead of a username.
To test our implementation, follow the steps below:
Prepare and perform a database migration.
python manage.py makemigrations
python manage.py migrate
1. start the Django development server by typing in the console:
python manage.py runserver
2. Open your browser and go to the registration URL, for example: http://127.0.0.1:8000/register/
. You will see the registration form we created earlier.
3. Fill out the form with your email address, password and repeated password. Make sure the password you provide meets security requirements, such as length and unique characters.
4. Click the "Register" button. If the form has been filled out correctly, you will be redirected to a login page with information about the successful creation of your account.
5. Navigate to the login URL, for example: http://127.0.0.1:8000/login/
. You will see the login form that we also created earlier.
6. Enter the email address and password you used during registration, and then click the "Login" button.
7. If your login information is correct, you will be redirected to the application's home page (or another page we defined after logging in).