Django处理多用户类型的方法介绍


Posted in Python onMay 18, 2019

起步

这是许多开发者在项目初期要面临的一个普遍问题。要怎样来处理多用户类型。

本文讲介绍对于不同场景和业务需求如何设计用户模型。为项目提供指导设计。

设计之前

在梳理用户设计之前,有几个前提需要遵守。

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)
  ...

总结

可以参照如下的流程图来帮助设计:

Django处理多用户类型的方法介绍

总的来说,始终都用一个用户模型来处理身份认证,不要在多有模型中存储用户名和密码。通常对 User 模型添加布尔标记位就能适应大多数情况。如果需要灵活的权限管理,可以使用Django内置的权限框架或第三方库。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python中函数传参详解
Jul 03 Python
Python实现将数据库一键导出为Excel表格的实例
Dec 30 Python
Centos 升级到python3后pip 无法使用的解决方法
Jun 12 Python
python 动态生成变量名以及动态获取变量的变量名方法
Jan 20 Python
详解Python字符串切片
May 20 Python
Python使用APScheduler实现定时任务过程解析
Sep 11 Python
在keras中获取某一层上的feature map实例
Jan 24 Python
利用django model save方法对未更改的字段依然进行了保存
Mar 28 Python
Python多个装饰器的调用顺序实例解析
May 22 Python
最简单的matplotlib安装教程(小白)
Jul 28 Python
利用python进行文件操作
Dec 04 Python
Selenium Webdriver元素定位的八种常用方式(小结)
Jan 13 Python
Django 配置多站点多域名的实现步骤
May 17 #Python
将Python字符串生成PDF的实例代码详解
May 17 #Python
Python Django框架单元测试之文件上传测试示例
May 17 #Python
Python django框架应用中实现获取访问者ip地址示例
May 17 #Python
Python Django框架实现应用添加logging日志操作示例
May 17 #Python
Python实现通过解析域名获取ip地址的方法分析
May 17 #Python
如何用C代码给Python写扩展库(Cython)
May 17 #Python
You might like
用PHP生成自己的LOG文件
2006/10/09 PHP
php 设计模式之 单例模式
2008/12/19 PHP
PHP  实现等比压缩图片尺寸和大小实例代码
2016/10/08 PHP
深入理解JavaScript系列(1) 编写高质量JavaScript代码的基本要点
2012/01/15 Javascript
JS实现淘宝幻灯片效果的实现方法
2013/03/22 Javascript
由点击页面其它地方隐藏div所想到的jQuery的delegate
2013/08/29 Javascript
JavaScript字符串对象toUpperCase方法入门实例(用于把字母转换为大写)
2014/10/17 Javascript
javascript中HTMLDOM操作详解
2014/12/11 Javascript
js实现人才网站职位选择功能的方法
2015/08/14 Javascript
js实现新年倒计时效果
2015/12/10 Javascript
利用CSS3在Angular中实现动画
2016/01/15 Javascript
详解angularjs结合pagination插件实现分页功能
2017/02/10 Javascript
js 将input框中的输入自动转化成半角大写(税号输入框)
2017/02/16 Javascript
详解Vue.use自定义自己的全局组件
2017/06/14 Javascript
用vue快速开发app的脚手架工具
2018/06/11 Javascript
浅谈让你的代码更简短,更整洁,更易读的ES6小技巧
2018/10/25 Javascript
基于Koa2写个脚手架模拟接口服务的方法
2018/11/27 Javascript
JavaScript寄生组合式继承原理与用法分析
2019/01/11 Javascript
JavaScript实现随机点名器实例详解
2019/05/07 Javascript
微信小程序实现搜索历史功能
2020/03/26 Javascript
jquery树形插件zTree高级使用详解
2019/08/16 jQuery
在pycharm中开发vue的方法步骤
2020/03/04 Javascript
解决vue中el-tab-pane切换的问题
2020/07/19 Javascript
[01:19:11]Ti4 循环赛第二日 NaVi.us vs iG
2014/07/11 DOTA
Python字符串的encode与decode研究心得乱码问题解决方法
2009/03/23 Python
[原创]Python入门教程5. 字典基本操作【定义、运算、常用函数】
2018/11/01 Python
计算机二级python学习教程(3) python语言基本数据类型
2019/05/16 Python
django-xadmin根据当前登录用户动态设置表单字段默认值方式
2020/03/13 Python
python利用蒙版抠图(使用PIL.Image和cv2)输出透明背景图
2020/08/04 Python
通过CSS3的object-fit来调整图片适配尺寸的技巧简介
2016/02/27 HTML / CSS
阿姆斯特丹城市卡:Amsterdam Pass
2019/12/01 全球购物
美国亚马逊旗下时尚女装网店:SHOPBOP(支持中文)
2020/10/17 全球购物
2014年村官工作总结
2014/11/24 职场文书
个人股份转让协议书范本
2015/01/28 职场文书
经理助理岗位职责
2015/02/02 职场文书
MySQL千万级数据表的优化实战记录
2021/08/04 MySQL