【Django】继承框架中用户模型基类AbstractUser扩展系统用户表字段

时间:2024-10-27 07:23:04

Django项目新建好app之后,通常情况下需要首要考虑的就是可以认为最重要的用户表,即users对应的model,它对于系统来说可以说是最基础的依赖。
实际上,我们在初始进行migration的时候已经同步生成了相应的user表,如下:
在这里插入图片描述
对应的表结构如下:
在这里插入图片描述
上述的这些字段通常都是可以保留使用的,但是为了方便扩展实际中是可以进行字段添加的,例如在users相应的app包中修改其对应的models.py文件

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

# 元组用于定义性别字段的可选值。第一个元素是存储在数据库中的值,第二个元素是显示给用户的友好名称
GENDER_CHOICES = (
    ("male", "男"),
    ("female", "女")
)

# 上述导入models模块是Django中提供的用于定义数据库模型的
# AbstractUser是Django的用户模型基类,提供了默认的用户字段和功能,比如用户名、密码、电子邮件等。这里直接继承
class UserProfile(AbstractUser):
    nick_name = models.CharField(max_length=50, verbose_name="昵称", default="")
    birthday = models.DateField(verbose_name="生日", null=True, blank=True)
    gender = models.CharField(verbose_name="性别", choices=GENDER_CHOICES, max_length=6)
    address = models.CharField(max_length=100, verbose_name="地址", default="")
    mobile = models.CharField(max_length=11, unique=True, verbose_name="手机号码")
    image = models.ImageField(verbose_name="用户头像", upload_to="head_image/%Y/%m", default="default.jpg")

    # Meta类用于定义与模型相关的元数据,这些元数据不会直接影响数据库的结构,但会影响模型的行为和在Django管理界面中的显示方式
    # verbose_name: 模型的单数名称,用于在Django管理界面显示
    # verbose_name_plural: 模型的复数名称,与单数名称相同
    class Meta:
        verbose_name = "用户信息"
        verbose_name_plural = verbose_name

    # __str__方法定义了模型实例的字符串表示。若有昵称,则返回昵称;否则返回用户名,这使得在Django管理界面中更容易识别用户
    def __str__(self):
        if self.nick_name:
            return self.nick_name
        else:
            return self.username

更新model还不够,还需要在项目中的配置文件settings.py中添加如下配置:

AUTH_USER_MODEL = "users.UserProfile"

为什么在settings.py中添加相应的配置为AUTH_USER_MODEL = "users.UserProfile"而不是AUTH_USER_MODEL = “apps.users.models.UserProfile”?

这是一种约定,用于指定自定义用户模型。AUTH_USER_MODEL 只需包含应用名和模型名,Django会根据应用的名称解析模型,而不是通过模块路径。只要确保在 INSTALLED_APPS中正确注册了users应用,Django就能找到对应的模型。

更新了用户模型之后就可以重新makemigrations和migrate了,数据库中将重新生成相应的用户表(可以在迁移之前先删除之前的表),如下:
在这里插入图片描述
在这里插入图片描述
可见添加的字段都更新进表中了。

说明:过程中如果出现报错,可以先将旧表及migrations中的相关文件都先删了然后再先makemigrations再migrate。