Email and Username Login with a Custom Django Authentication Backend cover image

Email and Username Login with a Custom Django Authentication Backend

• July 10, 2025

python django

Django is a powerful web framework that comes with a default username authentication backend. In this article, we will build a custom authentication backend for emails, allowing our Django application to accept either a username or email for login.

In your application's app directory, create a backends.py file.

|-- app/
    |-- __init__.py
    |-- backends.py

Include the code for the CustomModelBackend class.

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend

UserModel = get_user_model()

class CustomModelBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        if username is None or password is None:
            return
        try:
            user = UserModel.objects.get(email=username)
        except UserModel.DoesNotExist:
            # Run the default password hasher once to reduce the timing
            # difference between an existing and a nonexistent user (#20760).
            UserModel().set_password(password)
        else:
            if user.check_password(password) and self.user_can_authenticate(user):
                return user

Even though the username is the default positional argument, the function still checks the email field.

The CustomModelBackend inherits from the default ModelBackend, then we override the default authentication method to check the email field instead of the username. For Django to use the CustomModelBackend in your project settings, include the AUTHENTICATION_BACKENDS list.

AUTHENTICATION_BACKENDS = [
    'app.backends.CustomModelBackend',
    'django.contrib.auth.backends.ModelBackend'
]

Django will attempt to use email for authentication provided by CustomModelBackend; if it fails, then Django will use the default ModelBackend.