自定义用户表
新项目说明
我们 通过 一个新项目:校园信息管理平台,来继续深入对 Django的学习
自定义User表
Django 内置模块 contrib.auth 帮我们预置了一张用户表 user
,但是如果他不符合我们的需求,我们要重新定义,怎么办?
比如,这个项目的用户表需要新增一些字段,像 学号、备注、用户类型、真实姓名。
千万不要去改 Django 内置模块 contrib.auth.models 里面的类定义。(想一想,为什么?)
一种推荐的方式是:通过继承 contrib.auth.models 里面的 AbstractUser
类的方式
在你项目文件的 models 里面进行如下定义:
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.hashers import make_password,check_password
# 可以通过 命令 python manage.py createsuperuser 来创建超级管理员
# 就是在这User表中添加记录
class User(AbstractUser):
id = models.BigAutoField(primary_key=True)
# 用户类型
# 1: 超管 | 1000: 普通管理员 | 2000:学生 | 3000: 老师
usertype = models.PositiveIntegerField()
# 真实姓名
realname = models.CharField(max_length=30, db_index=True)
# 学号
studentno = models.CharField(
max_length=10,
db_index=True,
null=True, blank=True
)
# 备注描述
desc = models.CharField(max_length=500, null=True, blank=True)
REQUIRED_FIELDS = ['usertype', 'realname']
class Meta:
db_table = "by_user"
这样就在原来的 contrib.auth 里面的 user表的基础上
-
新增了 usertype、realname、phone、studentno、desc 这些字段
-
修改了 字段 id 的类型 为 BigAuto
-
声明了 用命令 createsuperuser 添加用户时, 'usertype','realname' 是需要提示用户填写的内容
然后,你需要告诉Django,使用这个表作为 系统的 user表。
就是 在 settings.py 中,添加如下设置
其中 myapp
改为你的 User 定义 所在的 django app 名称
一定要确保 这个 myapp 在你的 INSTALLED_APPS 里面设置了。
可能你会奇怪,我们为什么不能重新完全的重定义 User 表,一定要继承 contrib.auth.models 里面的 AbstractUser
类呢?
那是因为 Django内置的 认证 、权限 、 Session 机制 和 auth 模块深度绑定了,如果你需要使用 这些机制提供的方法,就不能抛弃 auth 里面的 user 表。
如果你不打算使用 Django内置的 认证 或者 Session 机制, 完全可以自己定义一张 User表。
那样,你就需要自己编写 认证流程 和 用户访问有效性的检查机制(比如基于 jwt token)了。
用户表中的 password
Django 的 用户表中 password 字段是需要特殊处理的。
Django 的密码不是明文存储的, 有好几种方式。具体说明,点击这里参考官方文档
我们可以使用 Django 库提供的方法 产生 password 字段值(通常是hash处理过)
from django.contrib.auth.hashers import make_password,check_password
# 添加一条记录
user = User.objects.create(
username = username,
# 使用 make_password 函数 产生password字段
password = make_password(data['password']),
# 其他字段...)
使用 Django auth 库里面的 authenticate 方法 就包含了 校验用户名、密码的过程,如下
from django.contrib.auth import authenticate, login, logout
# 使用 Django auth 库里面的 方法校验用户名、密码
user = authenticate(username=userName, password=passWord)
但是,有的系统设计完全弃用了 Django 的 auth、session 机制,我们仍然可以使用 hashers库里面的 check_password
方法 校验密码,如下
from django.contrib.auth.hashers import make_password,check_password
# 检查密码
if not check_password('密码明文', user.password):
return JsonResponse({'retcode': 1, 'msg': '密码错误'})
数据操作移到models中
为了实现后端系统的功能合理划分,建议把业务逻辑放在 view 代码中,而把数据底层处理放在 models中国。
这样, 处理HTTP请求的 view代码,只需要调用 models中的方法即可。
比如,处理 添加用户的view
def adduser(request):
# 从请求消息中 获取要添加客户的信息
# 并且插入到数据库中
data = request.param_dict['data']
# 直接调用 models中的添加 用户 的代码
ret = User.add(data)
return JsonResponse(ret)
而 models中 真正实现添加功能,如下
class User(AbstractUser):
id = models.BigAutoField(primary_key=True)
usertype = models.PositiveIntegerField()
realname = models.CharField(max_length=30, db_index=True)
class Meta:
db_table = "cimp_user"
# 直接在Model中用静态方法定义数据操作
@staticmethod
def add(data,usertype):
try:
username = data['username']
if User.objects.filter(username=username).exists():
return {'ret': 1, 'msg': f'登录名 {username} 已经存在'}
user = User.objects.create(
username = username,
password = make_password(data['password']),
usertype = usertype,
realname = data['realname'],
studentno = data['studentno'],
desc = data['desc']
)
return {'ret': 0,'id': user.id}