Django处理多用户类型的方法介绍
作者:栖迟于一丘 发布时间:2022-11-30 10:16:54
起步
这是许多开发者在项目初期要面临的一个普遍问题。要怎样来处理多用户类型。
本文讲介绍对于不同场景和业务需求如何设计用户模型。为项目提供指导设计。
设计之前
在梳理用户设计之前,有几个前提需要遵守。
1. 不要使用 Django 内置的 User 模型,尽管它能满足应用程序的所有要求。
正如官方Django文档强烈建议为新项目使用自定义用户模型。需求总是在变,只用固定的模型不太现实,并且一旦设置了 AUTH_USER_MODEL 后续再修改就很麻烦了。
2.无论最后选择什么方案,无论有什么业务,都始终只使用一个 Django 模型来处理身份验证。
永远都使用一个用户模型,这就是标题为什么是处理多用户类型而不是多用户模型。这也就能使用统一的身份认证机制。它仍然可以拥有多种用户类型。
方案
不同的项目要求设计出来的方案也是不同的,不妨先问问自己这几个问题:
需要维护多少种用户类型?
用户可以同时拥有多种角色吗?比如用户可以同时成为学生或老师吗?
不同用户类型是否需要存储不同的信息?
一种非常常见的情况就是拥有普通用户和管理员。在这种场景下,可以使用内置的 is_staff 来区分普通用户和管理员。实际上,内置模型中有两个字段来处理这种情况:is_staff 和 is_superuser 。is_staff 标志着用户是否允许登录 Django Admin 页面,至于该用户能做什么或不能做什么,就由权限框架来授权。而 is_superuser 是一个额外的标志,意味着拥有所有权限。所以这里可以看出来,权限有两个级别的管理。
需要维护多少种用户类型? 如果类型数量比较少,那就可以效仿Django的方式,用几个字段来简单表示:
class User(AbstractUser):
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
这可能是处理多种用户类型最简单的方法了。
另一种选择是,只用一个字段就来表示用户:
class User(AbstractUser):
USER_TYPE_CHOICES = (
(1, 'student'),
(2, 'teacher'),
(3, 'secretary'),
(4, 'supervisor'),
(5, 'admin'),
)
user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES)
超过 3 种类型可以选择这种方式。
用户可以同时拥有多种角色吗?
如果用户是可以同时承担多种角色的话,那么就需要一个额外的表表示它们多对多的关系,显然可以用到 ManyToManyField :
class Role(models.Model):
'''
The Role entries are managed by the system,
automatically created via a Django data migration.
'''
STUDENT = 1
TEACHER = 2
SECRETARY = 3
SUPERVISOR = 4
ADMIN = 5
ROLE_CHOICES = (
(STUDENT, 'student'),
(TEACHER, 'teacher'),
(SECRETARY, 'secretary'),
(SUPERVISOR, 'supervisor'),
(ADMIN, 'admin'),
)
id = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, primary_key=True)
def __str__(self):
return self.get_id_display()
class User(AbstractUser):
roles = models.ManyToManyField(Role)
这种方案其实并不常见,因为Django已经提供权限组的功能并拥有灵活的权限管理。你得评估下创建自定义权限组是否更好。
不同用户类型是否需要存储不同的信息? 如果存储的信息(如头像)与所有用户相关,那么最好的做法就是直接向用户模型添加额外的字段。
如果储存的信息只与特定的类型用户有关,那么可以用 OneToOneField 来进行拓展:
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
...
class Teacher(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
...
总结
可以参照如下的流程图来帮助设计:
总的来说,始终都用一个用户模型来处理身份认证,不要在多有模型中存储用户名和密码。通常对 User 模型添加布尔标记位就能适应大多数情况。如果需要灵活的权限管理,可以使用Django内置的权限框架或第三方库。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。
来源:http://www.hongweipeng.com/index.php/archives/1793/


猜你喜欢
- 本文实例为大家分享了微信小程序实现简单购物车的具体代码,供大家参考,具体内容如下微信小程序定制好看的购物车页面,实现购物车功能,希望对您有所
- 今天整理之前写的代码,发现在做数模期间写的用python实现的遗传算法,感觉还是挺有意思的,就拿出来分享一下。首先遗传算法是一种优化算法,通
- 计时器和延时器的概念 //--计时器 // 计时器ID号 setInterval(回调函数, 毫秒数); // 每隔指定毫秒数,调用一次回调
- 本文实例讲述了python通过BF算法实现关键词匹配的方法。分享给大家供大家参考。具体实现方法如下:#!/usr/bin/python# -
- 首先祝贺Echarts顺利的从Apache毕业,多了个响亮的名字:Apache ECharts,现在的官网地址在这里:传送门,首页相当的国际
- 本文实例讲述了PHP日志LOG类定义与用法。分享给大家供大家参考,具体如下:<?php/*** PHP log 类 */class C
- google 的设计原则中文1.易用性-聚焦在人,方便他们的生活,工作,梦想。2.速度-分秒必争3.简单-简单而强有力4.关联性- 对初学者
- 由于下学期报了一个Python的入门课程所以寒假一直在自己摸索,毕竟到时候不能挂科,也是水水学分最近心血来潮打算试试爬一下百度翻译肝了一天终
- 判断缩进代替大括号。冒号(:)后换号缩进。iftest=100if test>50: print('OK')print
- Bootstrap简介Bootstrap,来自 Twitter,是目前最受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JA
- 1.1全部php生成结构1.2html中嵌套php总结如下:html和php混写规则:php代码必须包在<?php ?>html
- 数据库,顾名思义,就是一个存储数据的大仓库,涵盖了多个方面的知识和应用。其优点和特性颇多,为多种编程语言的高效运行都提供了可靠又准确的信息来
- XML的嵌套处理 一般情况下,我们从数据库中查询得到的结果集可能很大,所以从服务器返回到客户端时,数据会被分成若干个页面分别进行传递。此时,
- 笛卡尔坐标系对于平面坐标系,任一射线OP与x轴夹角θ的范围,可以取[0,2π)或者(-π,&
- 回顾我们的python制作小游戏之路,几篇非常精彩的文章我们用python实现了坦克大战python制作坦克大战我们用python实现了飞船
- 相关文章推荐:各种北京2008奥运会倒计时Flash2008北京奥运会倒计时js代码 全套北京2008奥运会倒计时屏保<!DOCTYP
- 在这篇asp之数学函数里,我们将会以表格的形式,让大家了解到关于ASP中能用到的数学函数,里面包括一个数的绝对值、一个数的平方根
- 由于opencv读入图片数据类型是uint8类型,直接加减会导致数据溢出现象(1)用Numpy操作可以先将图片数据类型转换成int类型进行计
- 闭包(closure)是函数式编程的重要的语法结构。函数式编程是一种编程范式 (而面向过程编程和面向对象编程也都是编程范式)。在面向过程编程
- 作为一个网页设计师,不知道各位是否有这样的经历:客户给你的网站材料很多都是Word文档,虽然阅读起来很