Can't login using my custom login template.

Question :
I am using a custom login template to login to staff or non-staff members but the login page only allows the staff members to login in. When I try to log in using a non-staff member the page stays on the login page but when I log in with a superuser email it redirects to the blog page URL.

One thing before you give me the answer, Yes I have already added

AUTH_USER_MODEL = "accounts.Account"
LOGIN_REDIRECT_URL = "blogs"
LOGOUT_REDIRECT_URL = "blogs"

urls.py

from django.urls import path
from .views import CustomLogoutView, CustomRegistrationView, CustomLoginView

urlpatterns = [
    path("register/", CustomRegistrationView.as_view(), name="register"),
    path("login/", CustomLoginView.as_view(), name="login"),
    path("logout/", CustomLogoutView.as_view(), name="logout"),
]

views.py

from django.contrib.auth.views import LoginView, LogoutView
from django.urls import reverse_lazy
from django.views.generic import CreateView

from accounts.models import Account
from .forms import CustomRegistrationForm, CustomLoginForm


class CustomRegistrationView(CreateView):
    model = Account
    form_class = CustomRegistrationForm
    success_url = reverse_lazy("login")
    redirect_authenticated_user = True
    template_name: str = "accounts/register.html"
    success_message = "You registered successfully."


class CustomLoginView(LoginView):
    model = Account
    form_class = CustomLoginForm
    redirect_authenticated_user: bool = True
    success_url = reverse_lazy("dashboard")
    template_name: str = "accounts/login.html"


class CustomLogoutView(LogoutView):
    template_name: str = "accounts/logout.html"
    next_page = None

manager.py

from django.contrib.auth.models import BaseUserManager


class UserManager(BaseUserManager):
    def create_user(
        self, email, first_name, last_name, roll_no, password, department=None
    ):
        if not email:
            raise ValueError("User requires an Email")
        if not first_name:
            raise ValueError("User requires a First name")
        if not roll_no:
            raise ValueError("User requires a Roll Number")

        user = self.model(
            email=self.normalize_email(email),
            first_name=first_name,
            last_name=last_name,
            roll_no=roll_no,
            department=department,
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, first_name, last_name, password, department="OT"):
        if not email:
            raise ValueError("Admin requires an Email")
        if not first_name:
            raise ValueError("Admin requires a First name")

        user = self.model(
            email=self.normalize_email(email),
            first_name=first_name,
            last_name=last_name,
            department=department,
            is_staff=True,
            is_admin=True,
            is_superadmin=True,
            is_active=True,
            roll_number=None,
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.utils.translation import gettext_lazy as _
from .manager import UserManager

# AbstractUser can also be used because it already have some predefined model fields
# and we can add more if we want to.
class Account(AbstractBaseUser):
    # choices for departement
    class Department(models.TextChoices):
        CSE = "CSE", "COMPUTER SCIENCE"
        IT = "IT", "INFORMATION TECHNOLOGY"
        EE = "EE", "ELECTRIC ENGINEERING"
        CE = "CE", "CIVIL ENGINEERING"
        TE = "TE", "TEXTILE ENGINEERING"
        ME = "ME", "MECHANICAL ENGINEERING"
        OT = "OT", "OTHER"

    username = None
    email = models.EmailField(max_length=100, unique=True)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    roll_number = models.PositiveIntegerField(unique=True, null=True, blank=True)
    profile_picture = models.ImageField(upload_to="photos/profiles", blank=True)
    bio = models.TextField(null=True, blank=True)

    department = models.CharField(
        max_length=30,
        choices=Department.choices,
        blank=True,
        null=True,
    )

    # required
    date_joined = models.DateTimeField(auto_now=True)
    last_login = models.DateTimeField(auto_now_add=True)
    is_admin = models.BooleanField(default=False)
    is_superadmin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)

    USERNAME_FIELD: str = "email"
    REQUIRED_FIELDS = [
        "first_name",
        "last_name",
    ]

    objects = UserManager()

    def __str__(self) -> str:
        if self.roll_number and self.first_name:
            return "{} - {}".format(self.email, self.roll_number)

        else:
            return self.email

    # must add in
    def get_profile_image_filename(self):
        return str(self.profile_picture)[
            str(self.profile_picture).index(f"photos/profiles/{self.pk}/")
        ]

    def has_perm(self, perm, obj=None):
        return self.is_admin

    def has_module_perms(self, app_label):
        return True

form.py

from django import forms
from django import forms
from django.contrib.auth.forms import (
    UserCreationForm,
    AuthenticationForm,
)
from .models import Account


class CustomRegistrationForm(UserCreationForm):
    # DEPARTMENT_CHOICES = [
    #     ("CSE", "COMPUTER SCIENCE"),
    #     ("IT", "INFORMATION TECHNOLOGY"),
    #     ("EE", "ELECTRIC ENGINEERING"),
    #     ("CE", "CIVIL ENGINEERING"),
    #     ("TE", "TEXTILE ENGINEERING"),
    #     ("ME", "MECHANICAL ENGINEERING"),
    #     ("OT", "OTHER"),
    # ]
    email = forms.EmailField(
        max_length=100,
        required=True,
        widget=forms.TextInput(
            attrs={
                "type": "email",
                "id": "Email",
                "name": "email",
                "class": "mt-1 w-full rounded-md border-gray-200 bg-white text-sm text-gray-700 shadow-sm",
            }
        ),
    )
    first_name = forms.CharField(
        max_length=50,
        required=True,
        widget=forms.TextInput(
            attrs={
                "type": "text",
                "id": "FirstName",
                "name": "first_name",
                "class": "mt-1 w-full rounded-md border-gray-200 bg-white text-sm text-gray-700 shadow-sm",
            }
        ),
    )
    last_name = forms.CharField(
        max_length=50,
        required=True,
        widget=forms.TextInput(
            attrs={
                "type": "text",
                "id": "LastName",
                "name": "last_name",
                "class": "mt-1 w-full rounded-md border-gray-200 bg-white text-sm text-gray-700 shadow-sm",
            }
        ),
    )
    password1 = forms.CharField(
        required=True,
        widget=forms.PasswordInput(
            attrs={
                "class": "mt-1 w-full rounded-md border-gray-200 bg-white text-sm text-gray-700 shadow-sm",
                "type": "password",
                "id": "Password1",
                "placeholder": "Password",
            }
        ),
    )
    password2 = forms.CharField(
        required=True,
        widget=forms.PasswordInput(
            attrs={
                "class": "mt-1 w-full rounded-md border-gray-200 bg-white text-sm text-gray-700 shadow-sm",
                "type": "password",
                "id": "Password2",
                "placeholder": "Password",
            }
        ),
    )

    roll_number = forms.CharField(
        max_length=50,
        required=True,
        widget=forms.TextInput(
            attrs={
                "type": "text",
                "id": "RollNumber",
                "name": "roll_number",
                "class": "mt-1 w-full rounded-md border-gray-200 bg-white text-sm text-gray-700 shadow-sm",
            }
        ),
    )

    # department = forms.ChoiceField(
    #     choices=DEPARTMENT_CHOICES
    # )

    bio = forms.CharField(
        widget=forms.Textarea(
            attrs={
                "rows": 8,
                "cols": 50,
                "class": "mt-1 w-full rounded-md border-gray-200 bg-white text-sm text-gray-700 shadow-sm",
            }
        )
    )

    class Meta:
        model = Account
        fields = "__all__"


class CustomLoginForm(AuthenticationForm):
    username = forms.EmailField(
        max_length=100,
        required=True,
        widget=forms.TextInput(
            attrs={
                "class": "block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md bg-gray-800 border-gray-600 placeholder-gray-400 focus:border-blue-400 focus:border-blue-300 focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-blue-300",
                "placeholder": "Email Address",
                "type": "email",
            }
        ),
    )
    password = forms.CharField(
        required=True,
        widget=forms.TextInput(
            attrs={
                "class": "block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md bg-gray-800 border-gray-600 placeholder-gray-400 focus:border-blue-400 focus:border-blue-300 focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-blue-300",
                "type": "password",
                "placeholder": "Password",
            }
        ),
    )

login.html

{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block title %}
    Login
{% endblock title %}
{% block base %}
<div class="mx-auto max-w-screen-xl px-4 py-16 sm:px-6 lg:px-8">
  <div class="mx-auto max-w-lg text-center">
    <h1 class="text-2xl font-bold sm:text-3xl">Get started today!</h1>

    <p class="mt-4 text-gray-500">
      SIGN IN
    </p>
  </div>

  <form action="" method="post" class="mx-auto mt-8 mb-0 max-w-md space-y-4">
    {% csrf_token %}
    <div>
      <label for="email" class="sr-only">Email</label>

      <div class="relative">
        {{form.username}}
        <span class="absolute inset-y-0 right-4 inline-flex items-center">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            class="h-5 w-5 text-gray-400"
            fill="none"
            viewBox="0 0 24 24"
            stroke="currentColor"
          >
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207"
            />
          </svg>
        </span>
      </div>
    </div>

    <div>
      <label for="password" class="sr-only">Password</label>
      <div class="relative">
        {{form.password}}

        <span class="absolute inset-y-0 right-4 inline-flex items-center">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            class="h-5 w-5 text-gray-400"
            fill="none"
            viewBox="0 0 24 24"
            stroke="currentColor"
          >
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
            />
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
            />
          </svg>
        </span>
      </div>
    </div>

    <div class="flex items-center justify-between">
      <p class="text-sm text-gray-500">
        No account?
        <a class="underline" href="{% url 'register' %}">Sign up</a>
      </p>
      <button type="submit" class="ml-3 inline-block rounded-lg bg-teal-500 px-5 py-3 text-sm font-medium text-white hover:bg-teal-400 dark:hover:bg-teal-400">Sign In</button>
    </div>
  </form>
</div>
{% endblock base %}

Found the answer :slight_smile:
In manager.py file in the create_user function i forgot to add is_active=True