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 Django连接MySQL数据库做增删改查
Nov 07 Python
在Python中编写数据库模块的教程
Apr 29 Python
python执行使用shell命令方法分享
Nov 08 Python
深入理解Python中range和xrange的区别
Nov 26 Python
python通过百度地图API获取某地址的经纬度详解
Jan 28 Python
30秒轻松实现TensorFlow物体检测
Mar 14 Python
Python使用post及get方式提交数据的实例
Jan 24 Python
Python Django的安装配置教程图文详解
Jul 17 Python
keras 自定义loss model.add_loss的使用详解
Jun 22 Python
python 使用elasticsearch 实现翻页的三种方式
Jul 31 Python
详解python datetime模块
Aug 17 Python
详细介绍python操作RabbitMq
Apr 12 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 中include()与require()的对比
2006/10/09 PHP
对squid中refresh_pattern的一些理解和建议
2009/04/17 PHP
PHP函数篇之掌握ord()与chr()函数应用
2011/12/05 PHP
PHP实现的博客欢迎提示功能(很特别哦)
2014/06/05 PHP
ThinkPHP单字母函数(快捷方法)使用总结
2014/07/23 PHP
再谈PHP中单双引号的区别详解
2016/06/12 PHP
日期处理的js库(迷你版)--自建js库总结
2011/11/21 Javascript
jQuery aminate方法定位到页面具体位置
2013/12/26 Javascript
Javascript实现图片轮播效果(一)让图片跳动起来
2016/02/17 Javascript
AngularJS路由Ui-router模块用法示例
2017/05/29 Javascript
JS实现的简单四则运算计算器功能示例
2017/09/27 Javascript
Vue的实例、生命周期与Vue脚手架(vue-cli)实例详解
2017/12/27 Javascript
Vue CLI 2.x搭建vue(目录最全分析)
2019/02/27 Javascript
关于vue状态过渡transition不起作用的原因解决
2019/04/09 Javascript
Vue路由模块化配置的完整步骤
2019/08/14 Javascript
js+h5 canvas实现图片验证码
2020/10/11 Javascript
[54:47]Liquid vs VP Supermajor决赛 BO 第五场 6.10
2018/07/05 DOTA
[48:31]完美世界DOTA2联赛PWL S3 DLG vs Phoenix 第二场 12.17
2020/12/19 DOTA
Python+tkinter使用80行代码实现一个计算器实例
2018/01/16 Python
python微信跳一跳系列之自动计算跳一跳距离
2018/02/26 Python
python实现自主查询实时天气
2018/06/22 Python
Python通用循环的构造方法实例分析
2018/12/19 Python
详解用Python练习画个美队盾牌
2019/03/23 Python
python的reverse函数翻转结果为None的问题
2020/05/11 Python
python百行代码自制电脑端网速悬浮窗的实现
2020/05/12 Python
介绍一下内联、左联、右联
2013/12/31 面试题
关于Assembly命名空间的三个面试题
2015/07/23 面试题
C#中类(class)与结构(struct)的异同
2013/11/03 面试题
个人生活学习自我评价范文
2013/11/26 职场文书
见习期自我鉴定
2014/01/31 职场文书
初一新生军训方案
2014/05/22 职场文书
政风行风自查自纠报告
2014/10/21 职场文书
历史名人教你十五个读书方法,赶快Get起来!
2019/07/18 职场文书
Python趣味挑战之教你用pygame画进度条
2021/05/31 Python
在Python 中将类对象序列化为JSON
2022/04/06 Python
python实现手机推送 代码也就10行左右
2022/04/12 Python