使用自定义用户模型时,Django管理员中的“请更正以下错误”

Bud*_*hot 3 django

我正在开发Django应用程序,我完全按照以下说明构建了自定义用户。

现在,当我尝试从管理面板创建新用户时,收到此错误消息 在此处输入图片说明

所以不是很有用。另外,无论我使用“更改”表单还是“创建”表单,我都遇到相同的问题。

但是,如果我尝试通过外壳创建新用户,例如

MyUser.objects.create_user(email="test@gmail.com", password=None)
Run Code Online (Sandbox Code Playgroud)

有用。


故障排除

这是定制用户的模型:

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
Run Code Online (Sandbox Code Playgroud)
  • 一种解释是,它与某个字段有关MyUserblank=False但我的字段未显示该字段ModelForm。我仔细检查了,很好。

  • 另一个解释是,管理员创建表单的验证已某种程度上继承自的默认User模型,django.contrib.auth并且正在尝试从中查找User不存在的字段MyUser。我该如何检查?

  • 任何的想法?

Ran*_*ndO 5

我有一个类似的问题。但是它不在管理员表单中,而是在管理员列表中。我正在使用list_editable字段。当我保存更改时,我将收到“请更正以下错误”消息,并且未突出显示任何内容。

我的错误是我已将list_display中的第一个字段包含为list_editable。为了更正它,我在list_display字段的前面添加了“ id”。

  • 这似乎是一个错误。Django 不应该让你将所有的 list_display 都作为 list_editable 而是强制一个是不可编辑的链接,并在你尝试保存任何内容时抛出错误。 (2认同)

r1v*_*v3n 5

问题

我有一个类似的问题。但这很容易解决。


如何一步步解决?

首先我们需要谈谈覆盖,正如你之前所说的。Django 默认在模型中使用用户名字段。你需要在你的models.py 中像这样改变它:

USERNAME_FIELD = 'email'
Run Code Online (Sandbox Code Playgroud)

如果你仍然真的想覆盖很多代码,下一步:创建管理器。关于这一点:django 管理器 在您的自定义管理类中,您需要使用以下示例覆盖用户创建(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))
Run Code Online (Sandbox Code Playgroud)

只有在完成所有这些步骤之后,您才能关心覆盖现有表单。关于这个的 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', )
Run Code Online (Sandbox Code Playgroud)

此表单用于在您的管理员和用户更改中创建用户。只有现在您才能在 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 = ()
Run Code Online (Sandbox Code Playgroud)

请务必添加add_fieldsets并通过电子邮件覆盖排序。在 add_fieldsets 中,您需要 2 种类型的密码。如果只有 1 - 发生错误。顺便说一下,从你的屏幕上。


我希望这对遇到此问题的每个人都有帮助。

  • `add_fieldsets = (( None, { "classes": ("wide",),"fields": (..., "password1", "password2",)}))` 解决了我的问题。 (2认同)

Bud*_*hot 3

好的,谢谢你们的回答,但我的问题实际上来自于我的UserAdmin覆盖。

更具体地说,UserAdmin使用add_formform分别指代创建和更改形式。当我将变量命名为creation_form和 时change_form,它没有覆盖django.contrib.auth.models.User表单,这就是为什么某些字段未验证的原因,因为我的ModelForms 没有显示这些User字段。

现在我已经在我的自定义中重命名creation_formadd_formchange_formto ,它就像一个魅力:-)formUserAdmin