Can';t让Django自定义用户模型与管理员一起工作

Can';t让Django自定义用户模型与管理员一起工作,django,django-admin,Django,Django Admin,我创建了一个自定义用户模型(如下所示),并设法让注册和登录工作。但是,我在登录管理时遇到问题。特别是,即使“成功”创建了超级用户,我也无法登录到管理员并收到错误消息:“请为员工帐户输入正确的电子邮件地址和密码。请注意,这两个字段可能区分大小写。” 为了完整起见,我附加了以下代码。我知道很多,但任何建议都会有帮助。谢谢 models.py from django.db import models from django.contrib.auth.models import AbstractBase

我创建了一个自定义用户模型(如下所示),并设法让注册和登录工作。但是,我在登录管理时遇到问题。特别是,即使“成功”创建了超级用户,我也无法登录到管理员并收到错误消息:“请为员工帐户输入正确的电子邮件地址和密码。请注意,这两个字段可能区分大小写。”

为了完整起见,我附加了以下代码。我知道很多,但任何建议都会有帮助。谢谢

models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin

class UserManager(BaseUserManager):
    def create_user(self, email, password=None):
        if not email:
            raise ValueError('Users must have an email address')

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

    def create_superuser(self, email, password):
        user = self.create_user(email=email, password=password)
        user.is_admin = True
        user.is_superuser = True
        user.save(using=self._db)
        return user

class User(AbstractBaseUser, PermissionsMixin):
    """
    Custom user class.
    """
    email = models.EmailField('email address', unique=True, db_index=True)
    joined = models.DateTimeField(auto_now_add=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'

    def __str__(self):
        return self.email

    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
backends.py中的自定义后端

from django.conf import settings
from django.contrib.auth.models import check_password
from account.models import User

class EmailAuthBackend(object):
    """
    A custom authentication backend. Allows users to log in using their email address.
    """

    def authenticate(self, email=None, password=None):
        """
        Authentication method
        """

        try:
            user = User.objects.get(email=email)
            if user.check_password(password):
                return user
            else:
                print('Password not correct')
        except User.DoesNotExist:
            print('User does not exist')
            return None

    def get_user(self, user_id):
        try:
            user = User.objects.get(pk=user_id)
            if user.is_active:
                return user
            return None
        except User.DoesNotExist:
            return None
管理员

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm, ReadOnlyPasswordHashField
from .models import User as AuthUser
from django import forms


class CustomUserCreationForm(UserCreationForm):
    """ 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(UserCreationForm.Meta):
        model = AuthUser
        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 do not match.")
        return password2

    def save(self, commit=True):
        #Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class CustomUserChangeForm(UserChangeForm):
    password = ReadOnlyPasswordHashField(label="password",
                                         help_text="""Raw passwords are not stored, so there is no way to see this
                                         user's password, but you can change the password using <a href=\"password/\">
                                         this form</a>.""")

    class Meta(UserChangeForm.Meta):
        model = AuthUser
        fields = ('email', 'password', 'is_active', 'is_superuser', 'user_permissions')

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]


class AuthUserAdmin(UserAdmin):
    form = CustomUserChangeForm
    add_form = CustomUserCreationForm

    list_display = ('email', 'is_superuser')
    list_filter = ('is_superuser',)

    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Permissions', {'fields': ('is_active', 'is_superuser')}),
    )

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

    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ('groups', 'user_permissions',)

admin.site.register(AuthUser, AuthUserAdmin)
来自django.contrib导入管理
从django.contrib.auth.admin导入UserAdmin
从django.contrib.auth.forms导入UserCreationForm、UserChangeForm、ReadOnlyPasswordHashField
从.models导入用户作为AuthUser
来自django导入表单
类CustomUserCreationForm(UserCreationForm):
“”“用于创建新用户的表单。包括所有必填字段和重复密码。”“”
password1=forms.CharField(label='Password',widget=forms.PasswordInput)
password2=forms.CharField(label='Password Confirmation',widget=forms.PasswordInput)
类元(UserCreationForm.Meta):
model=AuthUser
字段=('email',)
def clean_密码2(自身):
#检查两个密码条目是否匹配
password1=self.cleaned\u data.get(“password1”)
password2=self.cleaned_data.get(“password2”)
如果password1和password2以及password1!=密码2:
raise forms.ValidationError(“密码不匹配”)
返回密码2
def save(self,commit=True):
#以哈希格式保存提供的密码
user=super(UserCreationForm,self).save(commit=False)
user.set_密码(自清理_数据[“password1”])
如果提交:
user.save()
返回用户
类CustomUserChangeForm(UserChangeForm):
password=ReadOnlyPasswordHashField(label=“password”,
help_text=“”未存储原始密码,因此无法查看此信息
用户的密码,但您可以使用“”更改密码
类元(UserChangeForm.Meta):
model=AuthUser
字段=(‘电子邮件’、‘密码’、‘是否活动’、‘是否超级用户’、‘用户权限’)
def clean_密码(自身):
#无论用户提供什么,都返回初始值。
#这是在这里完成的,而不是在现场,因为
#字段无权访问初始值
返回self.initial[“password”]
类AuthUserAdmin(UserAdmin):
form=CustomUserChangeForm
add_form=CustomUserCreationForm
列表显示=('email','is\u superuser')
列表\u筛选器=('is\u superuser',)
字段集=(
(无,{'fields':('email','password')}),
('Permissions',{'fields':('is_active','is_superuser')),
)
添加_字段集=(
(无{
'类':('wide',),
'fields':('email','password1','password2','is_superuser'))
),
)
搜索_字段=('email',)
排序=(‘电子邮件’,)
filter_horizontal=('groups'、'user_permissions',)
admin.site.register(AuthUser,AuthUserAdmin)

控制管理员访问权限的属性是
是\u staff
,而不是
是\u admin


如果出于任何原因希望保留当前字段,可以定义一个
is_staff()
方法并将其作为属性。

将Django升级到1.9版本。我已通过以下方式解决了此问题:

$ pip install django==1.9b1