Implementing a custom backend for email authentication

Hi everyone,

I want to create an authentication system in which the username is the user’s email adress like so :

models.py :

from django.db.models import EmailField, CharField
from django.contrib.auth.models import AbstractUser, BaseUserManager

class UserManager(BaseUserManager):
    def get_by_natural_key(self, username):
        user = UserModel.objects.get(email=username)
        return user

class UserModel(AbstractUser):
    username = None
    email = EmailField(max_length=20, unique=True, blank=False)
    password = CharField(max_length=20, blank=False)
    objects = UserManager()

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = []
    
    def __str__(self):
        return self.email

forms.py :

from django.forms import (
    ModelForm,
    Form,
    EmailField,
    CharField,
)
from .models import UserModel

class signupUserForm(ModelForm):
    password1 = CharField(max_length=20, required=True)
    password2 = CharField(max_length=20, required=True)

    class Meta:
        model = UserModel
        fields = ["email"]

class loginUserForm(Form):
    email = EmailField(max_length=20, required=True)
    password = CharField(max_length=20, required=True)

backends.py :

from django.contrib.auth.backends import BaseBackend

class EmailBackend(BaseBackend):
    def authenticate(self, username=None, password=None):
        try:
            user = UserModel.objects.get(email=username)
        except UserModel.DoesNotExist:
            return None
        return user

output :

>>> from site_app.forms import signupUserForm, loginUserForm
>>> from site_app.models import UserModel
>>> from site_app.models import UserManager
>>> from site_app.backends import EmailBackend
>>> form = signupUserForm({"email":"test@mail.com","password1":"pwd","password2":"pwd"})                                                             >>> form.is_valid()
True
>>> form.save()
<UserModel: test@mail.com>
>>> UserModel.objects.get(email="test@mail.com")
<UserModel: test@mail.com>
>>> form = loginUserForm({"email":"test@mail.com","password":"pwd"})
>>> form.is_valid()
True
>>> from django.contrib.auth import authenticate, login
>>> user = authenticate(username=form.cleaned_data["email"], password=form.cleaned_data["password"])
>>> user
None

Why does my “user” is None ?

Best Regards