在使用自定义用户模型创建超级用户后无法登录django admin

ber*_*kia 7 django django-models django-admin django-custom-manager

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

我希望用户只使用他们的电子邮件作为用户名.我也尽力在这里复制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   
Run Code Online (Sandbox Code Playgroud)

来自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)
Run Code Online (Sandbox Code Playgroud)

相关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',
)
Run Code Online (Sandbox Code Playgroud)

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

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"
}
}
]
Run Code Online (Sandbox Code Playgroud)

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

我希望我做的事情显然是错误的,感谢任何花时间仔细研究整个问题的人.

kir*_*chi 10

代码很好.问题是您只使用RemoteUserBackend而不是默认后端:

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.RemoteUserBackend',
)
Run Code Online (Sandbox Code Playgroud)

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

您可以添加默认的ModelBackend作为后备,如果您不想同时使用它们:

AUTHENTICATION_BACKENDS = (
        'django.contrib.auth.backends.RemoteUserBackend',
        'django.contrib.auth.backends.ModelBackend',
)
Run Code Online (Sandbox Code Playgroud)

或完全摆脱RemoteUserBackend并让您的应用程序验证默认方式.

希望这可以帮助.


小智 6

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

user.is_active = True
Run Code Online (Sandbox Code Playgroud)