I am trying to write a custom UserModel and Email Authentication backend. When I tried to override authenticate method. user=UserModel.objects.get(email=email) returned none.
Here are my models.py , authenticate.py, views.py,settings.py
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser,PermissionsMixin,BaseUserManager
from django.utils import timezone
# Create your models here.
class CustomUserManager(BaseUserManager):
def _create_user(self,firstname,lastname,email,password,**extra):
if not email:
raise ValueError('You have not provided a valid email')
email=self.normalize_email(email)
if not firstname and not extra['is_superuser']:
raise ValueError('You must have a first name')
if not lastname and not extra['is_superuser']:
raise ValueError('You must have a last name')
user=self.model(
email=email,
firstname=firstname,
lastname=lastname,
**extra
)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self,firstname=None,lastname=None,email=None,password=None,**extra):
extra.setdefault('is_staff',False)
extra.setdefault('is_superuser',False)
extra.setdefault('is_active',True)
return self._create_user(firstname,lastname,email,password,**extra)
def create_superuser(self,firstname='admin',lastname='',email=None,password=None,**extra):
extra.setdefault('is_staff',True)
extra.setdefault('is_superuser',True)
extra.setdefault('is_active',True)
return self._create_user(firstname,lastname,email,password,**extra)
class UserModel(AbstractBaseUser,PermissionsMixin):
firstname=models.CharField(max_length=100,default='')
lastname=models.CharField(max_length=100,default='')
email=models.EmailField(unique=True,default='',null=False,blank=False)
is_active=models.BooleanField(default=True)
is_superuser=models.BooleanField(default=False)
is_staff=models.BooleanField(default=False)
date_joined=models.DateTimeField(default=timezone.now)
last_login=models.DateTimeField(blank=True,null=True)
objects=CustomUserManager()
USERNAME_FIELD='email'
EMAIL_FIELD='email'
REQUIRED_FIELDS=[]
class Meta():
verbose_name='UserModel'
verbose_name_plural='UserModel'
def get_full_name(self):
return self.firstname + self.lastname
class Profile(models.Model):
firstname=models.CharField(max_length=100,null=False,default='')
lastname=models.CharField(max_length=100,null=False,default='')
email=models.EmailField(null=False,unique=True)
mobile=models.BigIntegerField()
about=models.TextField(max_length=400)
verified=models.BooleanField(verbose_name='verified',default=False)
def __str__(self):
return self.username
Authenticate.py
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth import get_user_model
class EmailAuthBackend(BaseBackend):
def authenticate(self, response, email=None, password=None, **kwargs):
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=email)
except UserModel.DoesNotExist:
return None
if user.check_password(password):
return user
else:
return None
def get_user(self,user_id):
try:
return get_user_model().objects.get(pk=user_id)
except get_user_model().DoesNotExist:
return None
Views.py
from django.shortcuts import render,redirect
from .models import *
from .authentication import EmailAuthBackend
from django.contrib.auth import logout,login
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
# Create your views here.
def Login(response):
if response.method=='POST':
email=response.POST.get('email')
password=response.POST.get('password')
user=EmailAuthBackend.authenticate(email,password)
print(user)
if user is not None:
if user.is_active:
login(response,user)
return redirect('verify')
else:
return HttpResponse('User is not active')
else:
return redirect('login')
return render(response, "users/screens/login.html", {})
def sign_up(response):
if response.method=='POST':
firstname=response.POST.get('firstname')
lastname=response.POST.get('lastname')
email=response.POST.get('email')
password=response.POST.get('password')
if UserModel.objects.filter(email=email).exists():
return HttpResponse('User with this email already exist')
else:
UserModel.objects.create(
firstname=firstname,
lastname=lastname,
email=email,
password=password,
)
return redirect('login')
return render(response, "users/screens/signup.html", {})
def forgot_password(response):
return render(response, "users/screens/forgot_password.html", {})
def verify(response):
return render(response, "users/screens/verify.html", {})
settings.py
#AUTHENTICATION BACKEND
AUTH_USER_MODEL='users.UserModel'
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'users.authentication.EmailAuthBackend',
]
I was expecting the user=UserModel.objects.get(email=email) to return the user object but I got none instead and the view redirected it to the login page itself.