Django 如何处理多用户类型

栏目: Python · 发布时间: 7年前

内容简介:这是许多开发者在项目初期要面临的一个普遍问题。要怎样来处理多用户类型。本文讲介绍对于不同场景和业务需求如何设计用户模型。为项目提供指导设计。在梳理用户设计之前,有几个前提需要遵守。

起步

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

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

设计之前

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

1. 不要使用 Django 内置的 User 模型,尽管它能满足应用程序的所有要求。

正如官方 Django文档 强烈建议为新项目使用自定义用户模型。需求总是在变,只用固定的模型不太现实,并且一旦设置了 AUTH_USER_MODEL 后续再修改就很麻烦了。

2.无论最后选择什么方案,无论有什么业务,都始终只使用一个 Django 模型来处理身份验证。

永远都使用一个用户模型,这就是标题为什么是处理多用户类型而不是多用户模型。这也就能使用统一的身份认证机制。它仍然可以拥有多种用户类型。

方案

不同的项目要求设计出来的方案也是不同的,不妨先问问自己这几个问题:

  • 需要维护多少种用户类型?
  • 用户可以同时拥有多种角色吗?比如用户可以同时成为学生或老师吗?
  • 不同用户类型是否需要存储不同的信息?

一种非常常见的情况就是拥有普通用户和管理员。在这种场景下,可以使用内置的 is_staff 来区分普通用户和管理员。实际上,内置模型中有两个字段来处理这种情况: is_staffis_superuseris_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 如何处理多用户类型》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First jQuery

Head First jQuery

Ryan Benedetti , Ronan Cranley / O'Reilly Media / 2011-9 / USD 39.99

Want to add more interactivity and polish to your websites? Discover how jQuery can help you build complex scripting functionality in just a few lines of code. With Head First jQuery, you'll quickly g......一起来看看 《Head First jQuery》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具