我创建了一个自定义用户模型(遵循此writeup),我设法让注册和登录工作。但是,我无法登录管理员。具体来说,即使在“成功”创建超级用户之后,我也无法登录管理员并收到错误消息:“请为员工帐户输入正确的电子邮件地址和密码。请注意,这两个字段可能区分大小写。”
为了完整起见,我附上以下代码。我知道这很多,但任何建议都会有所帮助。谢谢!
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
admin.py
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)
答案 0 :(得分:1)
控制管理员访问权限的属性为is_staff
,而不是is_admin
。
如果您想出于某种原因保留当前字段,可以定义is_staff()
方法并将其设为属性。
答案 1 :(得分:0)
将Django升级到1.9版本。我使用以下方法解决了这个问题:
$ pip install django==1.9b1