16

我一直在尝试使用成功创建的超级用户登录 django 管理面板,但无法获得正确的用户名/密码组合。

我希望用户只使用他们的电子邮件作为他们的用户名。我也尽了最大努力在此处复制 Django 文档中的示例。我已经删除了迁移、sycndb,除了登录到管理面板之外,一切正常。

相关代码:来自models.py

from django.db import models
from django.forms import ModelForm
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser

class UserManager(BaseUserManager):
    def create_user(self, email, password=None):
        """
        Creates and saves a User with the given email
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=UserManager.normalize_email(email),
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        user = self.create_user(email,
            password=password
        )

        user.is_admin = True
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user



class User(AbstractBaseUser):
    objects = UserManager()
    date_added = models.DateField(auto_now=False, auto_now_add=True)
    email = models.EmailField(unique=True, db_index=True)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __unicode__(self):
        return self.email

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    def get_full_name(self):
    # The user is identified by their email address
        return self.email

    def get_short_name(self):
    # The user is identified by their email address
        return self.email

    # On Python 3: def __str__(self):
    def __unicode__(self):
        return self.email

    def has_perm(self, perm, obj=None):

    # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):

    # Simplest possible answer: Yes, always
        return True

    def is_staff(self):

    # Simplest possible answer: All admins are staff
        return self.is_admin   

来自admin.py

from django.contrib import admin
from app.models import Relationship, Event, User
from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField


class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""

    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('email',)

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = User

    def clean_password(self):
        return self.initial["password"]





class UserAdmin(UserAdmin):
    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm


    list_display = ('email', 'is_admin')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Permissions', {'fields': ('is_admin',)}),
    )

    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

admin.site.register(User, UserAdmin)
admin.site.unregister(Group)

相关settings.py代码:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.contrib.auth.middleware.RemoteUserMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'relrem.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'relrem.wsgi.application'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'app',
    'south',

    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
)

AUTH_USER_MODEL = 'app.User'

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

创建超级用户并在表中查看的示例终端输出:

Email: name@sample.com
Password:
Password (again):
Superuser created successfully.

[
{
"pk": 1,
"model": "app.user",
"fields": {
    "is_active": true,
    "last_login": "2013-09-24T02:09:44.996Z",
    "is_admin": true,
    "date_added": "2013-09-23",
    "password": "",
    "email": "name@sample.com"
}
}
]

我认为这一定与密码的保存和返回方式有关,因为无论我做什么,我都会收到“请输入正确的员工帐户的电子邮件和密码。请注意,这两个字段可能区分大小写。” 信息。我在那里设置的密码是“样本”。我已经尝试删除所有与散列 pw 相关的代码并对其进行清理,但实际上仍会在用户表中返回一个散列。

我希望我在做一些明显错误的事情,提前感谢任何花时间研究整个问题的人。

4

3 回答 3

14

代码很好。问题是您仅使用 RemoteUserBackend 而不是默认后端

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

我自己从未使用过它,但从文档中可以清楚地看出,它只会检查您请求中的 REMOTE_USER 标头,从而使您的密码登录尝试无关紧要。

如果您不希望两者都可用,您可以添加默认的 ModelBackend 作为后备:

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

或完全摆脱 RemoteUserBackend 并让您的应用程序以默认方式进行身份验证。

希望这可以帮助。

于 2013-09-24T06:37:43.227 回答
5

也许您也可以尝试在 create_superuser 中设置

user.is_active = True
于 2021-04-18T22:40:10.297 回答
1

确保您的超级用户与您创建的配置文件之一相关联,也许通过手动将其插入到您的数据库中。

小心

于 2020-08-06T21:48:30.917 回答