Can't log in super users created on the django

2019-06-18 04:21发布

问题:

I'm trying to create superusers on the django admin backend, but somehow I can't get them to log in. Here's my user class,

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True, max_length=255)
    mobile = PhoneNumberField(null=True)
    username = models.CharField(null=False, unique=True, max_length=255)
    full_name = models.CharField(max_length=255, blank=True, null=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)


    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']
    objects = UserManager()

Here's the UserManager function to create super user,

class UserManager(BaseUserManager):

    def create_user(self, email, mobile=None, username=None, full_name=None, gender=None, birthday=None, password=None,
                    is_staff=False,
                    is_superuser=False, is_active=False, is_mobile_verified=False, is_bot=False, is_online=False,
                    is_logged_in=True):
        if not email:
            raise ValueError("Can't create User without a mobile number!")
        if not password:
            raise ValueError("Can't create User without a password!")
        user = self.model(
            email=self.normalize_email(email),
            mobile=mobile,
            username=username,
            full_name=full_name,
            gender=gender,
            birthday=birthday,
            is_staff=is_staff,
            is_superuser=is_superuser,
            is_active=is_active, 

        )
        user.set_password(password)
        return user

    def create_superuser(self, email, username, password=None):
        user = self.create_user(
            email,
            username=username,
            password=password,
            is_staff=True,
            is_superuser=True,
            is_active=True,
        )
        user.save(self._db)
        return user

    @property
    def is_superuser(self):
        return self.is_superuser

    @property
    def is_staff(self):
        return self.is_staff

    @property
    def is_active(self):
        return self.is_active

    @property
    def is_mobile_verified(self):
        return self.is_mobile_verified

    def has_perm(self, perm, obj=None):
        return self.is_staff or self.is_superuser

    def has_module_perms(self, app_label):
        return self.is_staff or self.is_superuser


    @is_staff.setter
    def is_staff(self, value):
        self._is_staff = value

    @is_superuser.setter
    def is_superuser(self, value):
        self._is_superuser = value

    @is_active.setter
    def is_active(self, value):
        self._is_active = value

Here's the relevant backend settings.

OAUTH2_PROVIDER = {
    # this is the list of available scopes
    'ACCESS_TOKEN_EXPIRE_SECONDS': 60 * 60 * 24,
    'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'},
    'OAUTH2_BACKEND_CLASS': 'oauth2_provider.oauth2_backends.JSONOAuthLibCore',
}

AUTHENTICATION_BACKENDS = (
        'django.contrib.auth.backends.ModelBackend',
)

# REST Framework
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}

I'm checking the is_staff and is_superuser to true on the creation form, still nothing. The created super user can't log in on the admin backend. What am I doing wrong here.

回答1:

First, you are using custom user model. In your settings file, do you tell django to use your model instead of default auth.models.User ?

Second,

you are calling self.create_user inside your create_superuser function.

Do you override the create_user function as well ?

If yes, please provide the implementation.

Update

You dont need to change implementation user mansger's functions as you did. IF you look at implementation of UserManger in django.auth.models. You can take inspiration from there and you avoid making a mistake - for example: you dont save model when you create standard user as you dont call save method.

I suggest to change your UserManager like this:

class UserManager(BaseUserManager):

    use_in_migrations = True

    def _create_user(self, email, password, 
**extra_fields):

        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_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)
        extra_fields.setdefault('is_active', False)

        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):

        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', 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)


回答2:

I created a new project with your code and I cannot reproduce your problem. Everything works fine on my side. However, I do notice a few things about your code:

First, in your settings.py, make sure you have set AUTH_USER_MODEL to your_app.User.

Second, in your UserManager class, I found things this:

@property
def is_staff(self):
    return self.is_staff

This looks like an error to me, as it would produces infinite recursions. I guess in your case, there is a catch-all clause in django's code so the RecursionError is silenced. This may very likely be the problem.