pythondjangodjango-modelsdjango-admindjango-authentication

Staff user can't login to django admin panel


I am trying to create a custom user model in my django app. But Whenever I tried to do so, I can't login with "staff user" created by the "super user" from the admin panel. It says:

"Please enter the correct username and password for a staff account. Note that both fields may be case-sensitve."

app name: Backend

Backend/models.py

from django.db import models
from django.contrib.auth.models import (
    AbstractBaseUser,
    BaseUserManager
)
# Create your models here.
class UserManager(BaseUserManager):
    
    def create_user(
        self,
        username = None,
        email = None,
        password = None,
        is_active = True,
        is_staff = False,
        is_admin = False
    ):
        if not username:
            raise ValueError("Users must have a username")
        if not password:
            raise ValueError("Users must have a password")
        if not email:
            raise ValueError("Users must have a email")
        
        user_obj = self.model(
            username = username
        )
        user_obj.email = self.normalize_email(email)
        user_obj.set_password(password)
        user_obj.is_active = is_active
        user_obj.is_staff = is_staff
        user_obj.is_admin = is_admin
        user_obj.save(using=self._db)
        return user_obj
        
    def create_staffuser(self, username, email, password):
        user_obj = self.create_user(
            username = username,
            email = email,
            password = password,
            is_staff = True
        )
        return user_obj
    
    def create_superuser(self, username, email, password):
        user_obj = self.create_user(
            username = username,
            email = email,
            password = password,
            is_staff = True,
            is_admin = True
        )
        return user_obj
        
class User(AbstractBaseUser):
    
    username = models.CharField(max_length=255, unique=True)
    email = models.EmailField(max_length=255, unique=True)
    is_active = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    
    objects = UserManager()
    USERNAME_FIELD = "username"
    REQUIRED_FIELDS = ["email"]
    
    def __str__(self):
        return self.username
        
    def get_full_name(self):
        return self.username
    
    def get_short_name(self):
        return self.username 
    
    def has_module_perms(self, app_label):
        return True 
    
    def has_perm(self, perm, ob=None):
        return True
    
        

Backend/admin.py

from django.contrib import admin
from Backend.models import(
    User
)
# Register your models here.
admin.site.register(User)

I added these lines to settings.py


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # my application
    'Backend'
]

# added lines
AUTH_USER_MODEL = "Backend.User"
AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
)

Thanks in advance.


Solution

  • I had a similar problem and found that passwords were not being hashed when creating new users though the admin interface. When using custom user models you need to register the correct ModelAdmin for it which is django.contrib.auth.admin.UserAdmin:

    from django.contrib import admin
    from django.contrib.auth.admin import UserAdmin
    from Backend.models import(
        User
    )
    
    admin.site.register(User, UserAdmin)
    

    ModelAdmin objects implement the logic of the Django's admin site and the auth logic is implemented by the UserAdmin class of the auth app. admin.site.register(User) will create a default ModelAdmin for User that implements just plain CRUD operations on it. That was the reason stored passwords were not being hashed in my case which made it always return wrong password error when trying to login later (since Django assumes stored passwords are hashed).

    Also managers are not used to create new objects in the admin site. You have to override the ModelAdmin class to customize it.