对于新开发系统,可以考虑从AbstractUser继承并扩展,增加需要的字段。
以下是一个例子
# 以下是自建了一个用户模型,并且已经在settings中替换了
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
chinese_name = models.CharField(max_length=50, unique=True, blank=False)
chinese_pass = models.CharField(max_length=100, blank=True)
chinese_addr = models.CharField(max_length=200, blank=True)
# 在settings中设定了替换默认的User模型
AUTH_USER_MODEL = 'app_models.CustomUser'
# 迁移后创建了自定义的用户表,名字是 <appname_customuser>
# 默认的auth_user表没有了,被此customuser表代替
# 而其它的系统表名字都不变,仍然是auth_groups /auth_permissions等
# 可以看到,customuser在User模型上,增加了上面自定义的三个字段
CREATE TABLE `app_models_customuser` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`password` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_login` datetime(6) DEFAULT NULL,
`is_superuser` tinyint(1) NOT NULL,
`username` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`first_name` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(254) COLLATE utf8mb4_unicode_ci NOT NULL,
`is_staff` tinyint(1) NOT NULL,
`is_active` tinyint(1) NOT NULL,
`date_joined` datetime(6) NOT NULL,
`chinese_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`chinese_pass` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`chinese_addr` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `chinese_name` (`chinese_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
# 看一下user permissions表,本来默认指向 auth_user的外键,现在指向了这个customuser表;
# 本来指向auth_permission的外键,依然不变
CREATE TABLE `app_models_customuser_user_permissions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customuser_id` int(11) NOT NULL,
`permission_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `app_models_customuser_us_customuser_id_permission_b33a0c84_uniq` (`customuser_id`,`permission_id`),
KEY `app_models_customuse_permission_id_948a0a60_fk_auth_perm` (`permission_id`),
CONSTRAINT `app_models_customuse_customuser_id_50275884_fk_app_model` FOREIGN KEY (`customuser_id`) REFERENCES `app_models_customuser` (`id`),
CONSTRAINT `app_models_customuse_permission_id_948a0a60_fk_auth_perm` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
因此,从AbstractUser扩展,实际上就是把默认的auth_user,替换成了自定义的CustomerUser。
以上CustomUser模型在后续可以修改定义,增减字段,然后执行迁移,也是很方便的。
在已有的系统增加,则可以考虑通过one to one的关系,增加一个额外的模型;
既可以使用django的auth backend,也可以扩展使用自定义的认证方式,例如使用多个标识(用户名/邮箱/手机呈等)登录。
直接修改模型保证新加的字段和原字段在同一张表里,每个用户进来的时候一次就获取到需要数据;
one-to-one意味着每个用户进来的时候,需要访问两张表才获取到全部数据,性能当然会降低,对系统压力更大一点;
不过,如果额外增加的信息是一个很少用到的信息,用one-to-one,能减少访问表的次数,对性能反而是有益的。
针对全部用户或针对全部访问请求的操作,可以用定制middleware实现
内置的User用户模型,认证方式很单一。通过定制的backend,实现username, email,手机号,或者任何其它需要的用户标识来进行认证;
以及不同用户标识必须有不同密码,也可以实现所有标识都使用同一个密码