【问题标题】:Problem adding user's email in Django admin在 Django 管理员中添加用户的电子邮件时出现问题
【发布时间】:2021-08-14 20:46:54
【问题描述】:

我创建了一个扩展 AbstractUser 的自定义模型,以便通过电子邮件而不是用户名对用户进行身份验证(但不想删除用户名,因为它也会被使用)。

这是我在运行第一次迁移之前所做的第一件事,除了在 Django 管理员中,一切正常,当我创建新用户时,我希望填写这些字段 用户名 电子邮件 密码

管理员只问我用户名和密码。我怎么也可以添加电子邮件?这是我的代码

models.py

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _


class CustomUserManager(BaseUserManager):
    """
    Custom user model manager where email is the unique identifier for 
    authentication instead of username.
    """
    def create_user(self, email, password, **extra_fields):
        """
        Create and save a User with the given email and password.
        """
        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()
        return user
    
    def create_superuser(self, email, password, **extra_fields):
        """
        Create and save a SuperUser with the given email and password.
        """
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError(_('Superuser must have is_staff=True.'))
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superuser must have is_superuser=True.'))
        return self.create_user(email, password, **extra_fields)


class User(AbstractUser):
    email = models.EmailField(_('email address'), unique=True)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []
    objects = CustomUserManager()

    def __str__(self):
        return self.email

admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User as CustomUser


class CustomUserAdmin(UserAdmin):
    model = CustomUser
    list_display = ('email', 'is_staff', 'is_active',)
    list_filter = ('eamil', 'is_staff', 'is_active',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Permissions', {'fields': ('is_staff', 'is_active')}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2', 'is_staff', 'is_active')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)

admin.site.register(CustomUser, UserAdmin)

我必须做什么?似乎一切都正确,但缺少必需的电子邮件字段。请注意,这只发生在我在管理员中使用添加用户功能时。当我创建超级用户或登录到管理员时,一切都按预期工作。

更新: 这是我的forms.py的内容

from django.contrib.auth.forms import UserCreationForm
# the user model was customized it should be invoked
from django.contrib.auth import get_user_model
from django.contrib.auth import forms as auth_forms
from .models import User as CustomUser


class UserChangeForm(auth_forms.UserChangeForm):
    class Meta(auth_forms.UserChangeForm.Meta):
        model = CustomUser

class UserCreationForm(auth_forms.UserCreationForm):
    class Meta(auth_forms.UserCreationForm.Meta):
        model = CustomUser
        fields = ("username", "email")


class CustomUserCreationForm(UserCreationForm):
    class Meta(UserCreationForm.Meta):
        # the user model was customized it should be invoked
        model = get_user_model()
        fields = UserCreationForm.Meta.fields + ("email",)

这里是我的 admin.py 的内容(更新)

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

class CustomUserAdmin(UserAdmin):
    model = CustomUser
    list_display = ('email', 'username', 'is_staff', 'is_active',)
    list_filter = ('eamil', 'username', 'is_staff', 'is_active',)
    form = UserChangeForm
    add_form = UserCreationForm
    
    fieldsets = (
        (None, {'fields': ('email', 'username', 'password')}),
        ('Permissions', {'fields': ('is_staff', 'is_active')}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'username', 'password1', 'password2', 'is_staff', 'is_active')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)

admin.site.register(CustomUser, UserAdmin)

但是我还是有同样的问题,我还是无法在/admin/users/user/add/中添加email字段

【问题讨论】:

    标签: django django-models django-forms django-admin django-users


    【解决方案1】:

    在您的代码中,我看到 admin.site.register(CustomUser, UserAdmin) 但您必须通过您的CustomUserAdmin 注册。 将您的 admin.py 代码更改为 admin.site.register(CustomUser, CustomUserAdmin)

    【讨论】:

      【解决方案2】:

      UserAdmin 类具有属性formadd_form,它们分别指向用于编辑和创建用户的表单类。您需要覆盖这些表单类并自己设置这些属性,因为这两个表单是为默认用户模型创建的。

      首先定义这些自定义表单:

      from django.contrib.auth import forms as auth_forms
      from .models import User as CustomUser
      
      class UserChangeForm(auth_forms.UserChangeForm):
          class Meta(auth_forms.UserChangeForm.Meta):
              model = CustomUser
      
      
      class UserCreationForm(auth_forms.UserCreationForm):
          class Meta(auth_forms.UserCreationForm.Meta):
              model = CustomUser
              fields = ("username", "email")
      

      接下来将这些设置在您的CustomUserAdmin

      from .forms import UserChangeForm, UserCreationForm
      
      
      class CustomUserAdmin(UserAdmin):
          # Your other attributes here
          form = UserChangeForm
          add_form = UserCreationForm
      

      【讨论】:

      • 我应该在哪里定义这些自定义表单?在 forms.py 或 admin.py 中?
      • @ionecum In forms.py(您也可以在自己的视图中使用这些表单)。
      • 还是不行。我仍然无法输入127.0.0.1:8000/admin/users/user/add中的电子邮件
      • 迁移文件是否可能导致冲突?我开始用一个简单的“通过”的空类来扩展原始用户的模型。然后,在第一次迁移之后,我添加了电子邮件字段。在第一次迁移后更改扩展的用户类可能会产生冲突吗?例如,如果我将 first_name 和 last_name 移动到另一个模型并在扩展用户模型中将它们设置为 None,它会产生迁移冲突吗?我有这个怀疑和怀疑。
      • 这是我所做的:在第一次迁移之前 1. 我用空类扩展了用户的模型 2. 我在设置中设置了 AUTH_USER_MODEL = 'users.User' 在第一次迁移之后:1 . 我将电子邮件设置为身份验证的用户名 email = models.EmailField(_('email address'), unique=True) USERNAME_FIELD = 'email' 我编辑了课程的其余部分。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-24
      • 2017-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多