如何在Django的用户模型中添加额外字段并在管理员界面中显示它们?

8
我正在学习Django,需要一些帮助。
我需要在我的用户模型(auth_user表在数据库中)中包含一个额外的布尔字段,并且在管理用户时在管理员界面中显示它,就像这个图片中的员工状态字段一样...
127:0.0.1:8000/admin/user:

enter image description here

和...

127.0.0.1:8000/admin/auth/user/2/change/ :

enter image description here

我对如何处理这个问题感到不确定。我明白我需要扩展AbstractUser模型,然后可能需要手动将字段添加到数据库中,但是如何更新新字段以适应管理界面的视图、表单和模板呢?我是否需要重写所有这些内容的Django管理源代码,还是有更简单的方法?

1
你可以为每个用户创建一个配置文件对象,然后在表单保存期间将附加字段保存到配置文件对象中。这些链接可能会有所帮助:https://dev59.com/-nNA5IYBdhLWcg3wL6oc,https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#a-full-example,http://stackoverflow.com/q/27150921/2610955。 - xtreak
5个回答

10

这是我做到的方式:

注意:这应该在你创建新项目时完成。

向用户模型添加字段:

models.py:

from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
   gender = models.BooleanField(default=True) # True for male and False for female
   # you can add more fields here.

重写默认用户模型:

settings.py:

# the example_app is an app in which models.py is defined
AUTH_USER_MODEL = 'example_app.User' 
在管理页面上显示模型:-
admin.py:
from django.contrib import admin
from .models import User

admin.site.register(User)

我收到了错误信息:Manager不可用。 - Shamsul Arefin

9
最好的方法是创建一个新的模型,并使用User OneToOneField。例如:
class UserProfile(models.Model):
   user = models.OneToOneField(User)
   phone = models.CharField(max_length=256, blank=True, null=True)
   gender = models.CharField(
        max_length=1, choices=(('m', _('Male')), ('f', _('Female'))),
        blank=True, null=True)

您可以在用户模型或用户资料模型中使用Django管理界面,并根据需要在管理界面中显示字段。


2
这些字段在迁移后如何显示? - Krishnadas PC

3

你有两个选择,它们分别是:

  1. 通过添加另一个模型并使用一对一关系将其链接到现有的用户模型来扩展现有的用户模型。 请参见此处

  2. 编写自己的用户模型并使用它,这对于新手来说可能会很困难。 请参见此处


0

2023年7月更新:

您可以使用用户模型OneToOneField()来扩展额外字段。*您还可以查看我的答案,了解如何使用AbstractUserAbstractBaseUserPermissionsMixin设置emailpassword身份验证。

首先,运行以下命令创建account应用程序:

python manage.py startapp account

然后,在`settings.py`中将`account`应用设置为INSTALLED_APPS,如下所示:
# "settings.py"

INSTALLED_APPS = [
    ...
    "account", # Here
]

然后,在account/models.py中创建UserProfile模型,如下所示。*user字段使用OneToOneField()扩展了User模型:
# "account/models.py"

from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(
        User, 
        verbose_name=_("user"), 
        on_delete=models.CASCADE
    )
    age = models.PositiveSmallIntegerField(_("age"))
    gender = models.CharField(_("gender"), max_length=20)
    married = models.BooleanField(_("married"))

然后,在`account/admin.py`中创建`UserProfileInline`和`UserAdmin`类,如下所示。*使用`admin.site.unregister(User)`取消注册默认注册的`User`模型是必要的,否则会出错:
# "account/admin.py"

from django.contrib import admin
from .models import UserProfile
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User

admin.site.unregister(User) # Necessary

class UserProfileInline(admin.TabularInline):
    model = UserProfile

@admin.register(User)
class UserAdmin(BaseUserAdmin):
    inlines = (UserProfileInline,)

然后,运行以下命令:
python manage.py makemigrations && python manage.py migrate

然后,运行以下命令:
python manage.py runserver 0.0.0.0:8000

最后,你可以按照下面的示例,扩展User模型,添加额外的字段:

enter image description here


0
#managers.py  Create new file.
from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _
class CustomUserManager(BaseUserManager):
    def create_user(self, email, password, **extra_fields):
        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):
        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)

#models.py  Create your models here.
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import gettext_lazy as _
from .managers import CustomUserManager
class User(AbstractBaseUser,PermissionsMixin):
    first_name =models.CharField(max_length=250)
    email = models.EmailField(_('email address'), unique=True)
    mobile =models.CharField(max_length=10)
    status = models.BooleanField(default=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []
    object =CustomUserManager()
    # add more your fields
    
#admin.py
from django.contrib import admin
from .models import User
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    list_display = ('email','mobile','password')
#setting.py
AUTH_USER_MODEL = 'users.User'

# run command
python manage.py makemigrations
python manage.py migrate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接