Please enter the correct email and password for a staff account

97 Views Asked by At

I created super user using python manage.py createsuperuser and i am sure that is_staff = True, is_superuser = True, is_active = True.

I used custom user, here is models.py:

from django.db import models
from django.contrib.auth.hashers import make_password
from django.contrib.auth.models import AbstractUser, Group, Permission, UserManager    


class CustomUserManager(UserManager):
    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')
        return self.create_user(email, password, **extra_fields)
    
    def _create_user(self, email, password, **extra_fields):
            email = self.normalize_email(email)
            user  = self.model(email=email, **extra_fields)
            user.password = make_password(password)
            user.save(using=self._db)
            return user
        
    def create_user(self, email, password=None, **extra_fields):
            extra_fields.setdefault('is_staff', False)
            extra_fields.setdefault('is_superuser', False)
            return self._create_user(email, password, **extra_fields)
        
        

class User(AbstractUser):
    email    = models.EmailField(max_length=254, unique=True)
    username = None
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = [] 
    objects = CustomUserManager() # use the custom manager
    
    def __str__(self):
        return self.email

the data in database

why can't login into the admin panal?

1

There are 1 best solutions below

1
KingRanTheMan On

Short Answer: The problem is inside your create_superuser method.

You finish the method by calling self.create_user, when you should be calling self._create_user (note the prepended underscore).

Make that change and your code will work and you'll be able to log into the admin panel. Explanation below.


Long Answer: When you call self.create_user(email, password, **extra_fields), your current create_user method will always override the is_staff and is_superuser extra_fields to be False, even though you pass them to the method as True. See below.

ORIGINAL CODE:

class CustomUserManager(UserManager):
    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)  ## IS TRUE HERE
        extra_fields.setdefault('is_superuser', True)  ## IS TRUE HERE
        extra_fields.setdefault('is_active', True)  ## IS TRUE HERE & WILL REMAIN SO

        if extra_fields.get('is_staff') is not True:  ## STILL TRUE
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:  ## STILL TRUE
            raise ValueError('Superuser must have is_superuser=True.')
        return self.create_user(email, password, **extra_fields)  ## STILL TRUE
                ## ^ THIS CALL HERE, WITHOUT UNDERSCORE, CAUSES THE PROBLEM                 
    
    def _create_user(self, email, password, **extra_fields): 
            email = self.normalize_email(email)
            user  = self.model(email=email, **extra_fields)
            user.password = make_password(password)
            user.save(using=self._db)
            return user
        
    def create_user(self, email, password=None, **extra_fields):  ## BOTH TRUE
            extra_fields.setdefault('is_staff', False)  ## IS STAFF NOW FALSE !!! 
            extra_fields.setdefault('is_superuser', False)  ## IS SUPERUSER NOW FALSE
            return self._create_user(email, password, **extra_fields)  ## SENT TO _CREATE_USER AS FALSE 

If you make the below change, it should work.

UPDATED CODED:

class CustomUserManager(UserManager):
    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')
        return self._create_user(email, password, **extra_fields)  ## CHANGE HERE!
                ## ^ UNDERSCORE ADDED, PROBLEM SHOULD NOW BE FIXED
    
    def _create_user(self, email, password, **extra_fields):
            email = self.normalize_email(email)
            user  = self.model(email=email, **extra_fields)
            user.password = make_password(password)
            user.save(using=self._db)
            return user
        
    def create_user(self, email, password=None, **extra_fields):
            extra_fields.setdefault('is_staff', False)
            extra_fields.setdefault('is_superuser', False)
            return self._create_user(email, password, **extra_fields)

Let me know if any issues persist.