使用自定义用户模型创建超级用户后,无法登录到django管理员 [英] Can't login to django admin after creating a super user with a custom user model

查看:1732
本文介绍了使用自定义用户模型创建超级用户后,无法登录到django管理员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've been trying for hours to login to the django admin panel with a successfully created superuser but cannot get the right username/pw combo right.

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

I want users to just use their email as their username. I've also done my best to replicate the example in the Django docs here. I've deleted migrations, sycndb, and everything works except logging in to the admin panel.

相关代码:
模型。 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',
)

从创建的样本终端输出超级用户并在表格中查看:

Sample terminal output from creating a superuser and viewing it in a table:

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并清理相关的所有代码,但实际上仍然返回用户表中的哈希。

I think it must be something to do with the way the password is being saved and returned, because no matter what I do I get the "Please enter the correct email and password for a staff account. Note that both fields may be case-sensitive." message. My password I set there was "sample". I've tried removing all of the code related to hashing the pw and cleaning it, but that actually still returns a hash in the user table.

我希望我做的事情明显错误,谢谢任何人花时间查看这个整个问题。

I hope I'm doing something obvious wrong, thanks in advance to anyone who takes the time to look through this whole question.

推荐答案

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

The code is fine. The problem is you're using the RemoteUserBackend exclusively, instead of the default backend:

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

我从来没有使用过,但是从文档很明显,它只会检查您的请求中的REMOTE_USER标头,从而使您的密码登录尝试不相关。

I've never used it myself, but from the docs it's clear that it'll only check for a REMOTE_USER header in your requests, thus making your password login attempts irrelevant.

如果您不能同时使用,则可以将默认的ModelBackend添加为后备项:

You could add the default ModelBackend as a fallback, if you wan't to have both available:

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

或摆脱RemoteUserBackend allt一起,让你的应用程序以默认方式进行身份验证。

or get rid of the RemoteUserBackend alltogether and have your app authenticate the default way.

希望这有帮助。

这篇关于使用自定义用户模型创建超级用户后,无法登录到django管理员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆