我正在开发一个Django应用程序,我完全遵循these instructions来构建自定义用户。
现在,当我尝试从管理面板创建新用户时,收到此错误消息
所以不是很有用。我是否也使用“更改”表单或“创建”表单时遇到同样的问题。
但是如果我尝试通过shell创建一个新用户,比如
MyUser.objects.create_user(email="test@gmail.com", password=None)
它有效。
以下是自定义用户的模型:
class MyUser(AbstractBaseUser):
"""
A base user on the platform. Users are uniquely identified by
email addresses.
"""
email = models.EmailField(
verbose_name = "Email address",
max_length = 100,
unique = True
)
is_active = models.BooleanField(default=True, blank=True)
is_admin = models.BooleanField(default=False, blank=True)
@property
def is_staff(self):
return self.is_admin
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ()
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def __unicode__(self):
return self.email
def has_perm(self, perm, obj=None):
'''Does the user have a specific permission?'''
return True
def has_module_perms(self, app_label):
'''Does the user have permissions to view the app `app_label`?'''
return True
一种解释是,它与MyUser
的{{1}}字段有关,但我的blank=False
未显示该字段。我仔细检查过,没关系。
另一种解释是,管理员创建表单的验证以某种方式继承自ModelForm
的默认User
模型,并且它正试图从django.contrib.auth
中找到一个字段在User
中不存在。我该怎么检查?
有什么想法吗?
答案 0 :(得分:5)
我有类似的问题。但它不在管理员表单中,而是在管理员列表中。我正在使用list_editable字段。当我保存更改时,我会收到“请更正下面的错误”消息,但没有突出显示。
我的错误是我将list_display中的第一个字段包含为list_editable。为了纠正它,我将'id'添加到list_display字段的前面。
答案 1 :(得分:1)
我认为这可以提供帮助,因为CharField
中的密码AbstractBaseUser
将blank
属性设置为默认为False
:
class MyUser(AbstractBaseUser):
def __init__(self, *args, **kwargs):
super(MyUser, self).__init__(*args, **kwargs)
passwd = [field for field in self._meta.fields if field.attname is 'password']
if passwd:
passwd[0].blank = True
答案 2 :(得分:0)
好的,谢谢你的答案但我的问题实际上来自我的UserAdmin
覆盖。
更具体地说,UserAdmin
分别使用add_form
和form
来指代创建和更改表单。当我命名我的变量creation_form
和change_form
时,它没有覆盖django.contrib.auth.models.User
表单,这就是为什么有些字段没有验证,因为我的ModelForm
没有显示User
1}}字段。
现在我已将creation_form
重命名为add_form
,将change_form
重命名为我的自定义form
内的UserAdmin
,它就像一个魅力: - )
答案 3 :(得分:0)
我有类似的问题。 但这很容易解决。
首先,正如您之前所说,我们需要讨论覆盖。 Django默认情况下在模型中使用用户名字段。您需要在 models.py 中将其更改为:
USERNAME_FIELD = 'email'
如果您仍然真的想覆盖大量代码,则下一步:创建管理器。关于此事:django managers 在您的自定义管理类中,您需要使用以下示例覆盖用户创建(create_user方法)和create_superuser方法。
def create_user(self, email, password, **extra_fields):
"""
Create and save a User with the given email and password.
"""
log.debug(f'Creating user: {email}')
if not email:
raise ValueError(_('The email must be set'))
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
log.info('Created user %s', repr(user))
只有完成所有这些步骤,您才可以考虑覆盖现有的表单。 关于此的Django文档:https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#custom-users-admin-full-example 实施:
CustomUserCreationForm(UserCreationForm)类:
class Meta(UserCreationForm):
model = CustomUser
fields = ('email', )
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('email', )
此表单用于在您的管理员中创建用户和更改用户。 而且只有现在,您可以在admin.py中添加代码,并像这样更改UserAdmin:
@admin.register(CustomUser)
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('first_name', 'last_name',)}),
('Permissions', {
'fields': ('is_admin',),
}),
('Important dates', {'fields': ('last_login',)}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2', 'is_admin', 'is_root', )}
),
)
list_display = ('email', 'first_name', 'last_name', 'is_admin', 'created_at', 'updated_at',)
list_filter = ('is_admin',)
search_fields = ('email', 'first_name', 'last_name',)
ordering = ('email',)
filter_horizontal = ()
请确保添加 add_fieldsets 并通过电子邮件覆盖订购。 在add_fieldsets中,您需要两种密码。如果只有1-发生错误。顺便说一下,在屏幕上。
希望这对遇到此问题的所有人有所帮助。