Django管理员不允许超级用户登录(自定义用户模型)

问题描述 投票:1回答:1

我创建了一个自定义用户类,该类似乎正常工作,但是每当我尝试登录到管理员时,都会在登录页面上不断出现以下错误:

请输入员工帐户的正确用户名和密码。请注意,两个字段都可能区分大小写。

我已经创建了几个超级用户,这些超级用户都已将is_staff / is_superuser / is_active标志设置为True正确地保存到了DB,如下所示:

CustomUser.objects.all().values()
<QuerySet [{'id': 1, 'password': 'test', 'last_login': None, 'is_superuser': True, 'username': 'test1', 'first_name': '', 'last_name': '', 'email': '[email protected]', 'is_staff': True, 'is_active': True, 'date_joined': datetime.datetime(2020, 6, 1, 0, 17, 30, 297149, tzinfo=<UTC>), 'role_id': 1, 'user_type_id': 1, 'created_by_id': None, 'update_date': datetime.datetime(2020, 6, 1, 0, 17, 30, 298524, tzinfo=<UTC>), 'updated_by_id': None}]>

我对我做错的事感到正式困惑,请帮助我弄清楚这件事...

models.py:

from django.db import models
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.conf import settings


class UserType(models.Model):
    """
    This model defines the types of users which are allowed to be created in the application. Examples include:
    API Read Only User
    API Full CRUD User
    Business User
    """
    name = models.CharField(max_length=50, blank=False, null=False)
    description = models.TextField()
    active = models.BooleanField(default=True)
    creation_date = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, null=True, blank=True,
                                   related_name='user_type_created_by')
    update_date = models.DateTimeField(auto_now=True)
    updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, null=True, blank=True,
                                   related_name='user_type_updated_by')


class Role(models.Model):
    """
    This model defines the job code/organization role a particular user is related to within their organization.
    Examples include:
    System User
    Business User
    Business User Manager
    """
    name = models.CharField(max_length=50)
    description = models.TextField()
    active = models.BooleanField(default=True)
    creation_date = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, null=True, blank=True,
                                   related_name='role_created_by')
    update_date = models.DateTimeField(auto_now=True)
    updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, null=True, blank=True,
                                   related_name='role_updated_by')


class CustomBaseUserManager(BaseUserManager):
    """
    Defined a custom base user manager class so as operations are executed against the CustomUser model, application
    specific fields can be utilized.
    """

    def create_user(self, role, user_type, username=None, email=None, password=None):
        # Verify that email was submitted
        if not email:
            raise ValueError('Email is required to create a user')
        else:
            email = BaseUserManager.normalize_email(email)

        # If no username was submitted but email was, assign email to the username
        if not username:
            username = email

        # Validate and get role ID from Role model
        role = Role.objects.get(id=role, active=True)

        # Validate and get the user_type ID from UserType model
        user_type = UserType.objects.get(id=user_type, active=True)

        user = self.model(
            email=email,
            username=username,
            role=role,
            user_type=user_type
        )

        user.set_password(password)
        user.save(using=self._db)

        return user

    def create_superuser(self, role, user_type, username=None, email=None, password=None):


# Verify that email was submitted
    if not email:
        raise ValueError('Email is required to create a user')
    else:
        email = BaseUserManager.normalize_email(email)

    # If no username was submitted but email was, assign email to the username
    if not username:
        username = email

    # Validate and get role ID from Role model
    role = Role.objects.get(id=role, active=True).id

    # Validate and get the user_type ID from UserType model
    user_type = UserType.objects.get(id=user_type, active=True).id

    user = self.create_user(
        email=email,
        username=username,
        role=role,
        user_type=user_type
    )

    user.is_staff = True
    user.is_superuser = True
    user.is_active = True
    user.is_admin = True
    user.set_password(password)
    user.save(using=self._db)

    return user


class CustomUser(AbstractUser):
    """
    This is a custom user model allowing for the required relationship between a user and a specific role as defined
    by the organization. The only roles which will be allowed to be assigned to users are those which are active at the
    time the user is being created.
    """

    role = models.ForeignKey(Role, on_delete=models.DO_NOTHING, limit_choices_to={'active': True}, null=False,
                             blank=False)
    user_type = models.ForeignKey(UserType, on_delete=models.DO_NOTHING, limit_choices_to={'active': True}, null=False,
                                  blank=False)
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, null=True, blank=True,
                                   related_name='user_created_by')
    update_date = models.DateTimeField(auto_now=True)
    updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, null=True, blank=True,
                                   related_name='user_updated_by')

    objects = CustomBaseUserManager()

    REQUIRED_FIELDS = AbstractUser.REQUIRED_FIELDS + [
        'role',
        'user_type'
    ]

    def get_full_name(self):
        """
        Return the first_name plus the last_name, with a space in between.
        """
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def __str__(self):
        return '{} <{}>'.format(self.get_full_name(), self.email)

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

settings.py:

"""
Django settings for CategoryManager project.

Generated by 'django-admin startproject' using Django 3.0.6.

For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/

SESSION_COOKIE_DOMAIN = '127.0.0.1:8000/'

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'l%sn*03#ls^d6e5e-&)u93lyqzvh$bh1nij)ye2h4la$&jz^t!'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'Users',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'CategoryManager.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'CategoryManager.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Custom user definition
AUTH_USER_MODEL = 'Users.CustomUser'

# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

AUTHENTICATION_BACKENDS = (
    # Needed to login by custom User model, regardless of `allauth`
    "django.contrib.auth.backends.ModelBackend",
)

# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'
django django-models django-admin django-custom-user
1个回答
0
投票

在create_superuser方法下,将user = self.model更改为user = self.create_user

© www.soinside.com 2019 - 2024. All rights reserved.