【Django】有关多用户管理的一点小经验分享

前言

最近,笔者因为需要开发一个系统作为毕设的展示,因此就产生了有关多用户管理的问题。在这里我把自己的需求重新阐明一下:能够通过Django自带的用户管理框架,实现多用户的管理,例如登录、登出、session、有效期等管理。
翻看很多同行写的文章,发现有关Django的多用户开发很多都含糊其词。主要原因是因为Django的django-admin框架的用户管理要么是用其自带的User类作为用户管理类,要么是自定义用户类别,并继承AbstractUser类。但是,无法实现两个或者多个类同时继承AbstractUser类,并且在settings.py文件中,AUTH_USER_MODEL也仅仅允许添加一个类。因此为了达到我们能够实现的需求,我有如下的设计思想,这个思想在后续的实践中证明可行。

实现

假设有用户类型A和用户类型B两中用户。

Step1:定义一个User类,使其继承AbstractUser类。

class User(AbstractUser):
is_type1 = models.BooleanField(default=False)
is_type2 = models.BooleanField(default=False)

# 这里添加三类用户的除Django-admin框架的User类属性外的额外属性
# 比如姓名
name = models.CharField(max_length=100)

通过上面的代码,可以清楚的看到,User类中设置一个布尔标志,来对用户角色加以区分。
这样设计的好处就是将不同类型的用户进行了统一化。

Step2:定义用户类型1的用户类和用户类型2的用户类

#这里是用户类型1的定义
class User_Type_1(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
# 一类用户的特有属性
user_type_1_teyoushuxing = models.CharField(max_length=200)

class Meta:
db_table = 'tb_user_type_1' # 修改表名
verbose_name = '第一类用户管理' # 管理系统后台显示名称
verbose_name_plural = verbose_name # 后台显示

#这里是用户类型2的定义
class User_Type_2(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
# 二类用户的特有属性
user_type_2_teyoushuxing = models.CharField(max_length=200)

class Meta:
db_table = 'tb_user_type_2' # 修改表名
verbose_name = '第二类用户管理' # 管理系统后台显示名称
verbose_name_plural = verbose_name # 后台显示

我们可以看到,通过代码

user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)

将User和两类用户进行了绑定,这样做我们就实现了对User的一个扩展,同时实现了不同用户之前的互不干扰。

Step3:在注册创建用户时

# 创建用户
try:
user = User.objects.create_user(
username=username,
password=password,
name=name
)
usertype_1 = User_Type_1.objects.create(user=user, user_type_1_teyoushuxing=user_type_1_teyoushuxing)
except DatabaseError as e:
logger.error(e)
return HttpResponseBadRequest('注册失败')

Step4:在登录用户时

from django.contrib.auth import authenticate
# 默认认证方法是针对username字段进行用户名的判断
user = authenticate(username=username, password=password)
if user is None:
return HttpResponseBadRequest('用户名或者密码错误')

直接使用内置的authenticate获取用户即可,然后根据扩展属性名来获取扩展的特有属性即可。

Author: Frederic Niu
Link: https://www.fredericniu.cn/2021/04/05/【Django】有关多用户管理的一点小经验分享/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
我的公众号