专栏首页数据云团Django实战-信息资讯-重构 USER 模型

Django实战-信息资讯-重构 USER 模型

与之前的生鲜电商项目相比较,本次的用户应用模型层会更深入复杂,涉及到创建超级用户、创建普通用户和用户权限。

一、指定自定义的用户模型

① Django 自定义的 User model 满足一些最低要求:

  • 模型必须有一个唯一的字段可被用于识别目的。可以是一个用户名、电子邮件或任何其它独特属性。
  • 定制一个 User model 最简单的方式是构造一个兼容的用户模型继承于 AbstractBaseUser。
  • AbstractBaseUser 提供了 User 类最核心的实现,包括哈希的 password 和 标识的密码重置。

② AbstractBaseUser 的子类必须定义的关键的字段和方法:

  • USERNAME_FIELD

必须设置。设置认证标识,设置成标识的字段 unique=True

# USERNAME_FIELD 这个属性是以后在使用authenticate 进行验证的字段
USERNAME_FIELD = 'telephone'
  • REQUIRED_FIELDS

必须设置。当通过 createsuperuser 管理命令创建一个用户时,用于提示的一个字段名称列表。

# 这个属性是用来,以后在命令行中使用createsuperuser命令的时候,会让你输入的字段
# 只用创建超级管理员的时候,就会让你输入 USERNAME_FIELD 指定的字段
# 现在 USERNAME_FIELD 指定的字段是 telephone ,以及password 这个字段不写也会让你输入
REQUIRED_FIELDS = ['username']
  • is_active

必须定义。一个布尔属性,标识用户是否是“active” 激活。AbstractBaseUser 默认为 True。

# 是否激活
is_active = models.BooleanField(default=True)
  • get_full_name()

必须定义。long 格式的用户标识。

def get_full_name(self):
    return self.username
  • get_short_name()

必须定义。short 格式的用户标识。

def get_short_name(self):
    return self.username

③ AbstractBaseUser 的子类可以使用的方法:

  • get_username()

返回 USERNAME_FIELD 的值

  • is_anonymous()

一直返回 False。用来区分 AnonymousUser

  • is_authenticated()

一直返回 True。用来告诉用户已被认证

  • set_password(raw_password)

设置密码。按照给定的原始字符串设置用户的密码。不保存 AbstractBaseUser 对象。如果没有给定密码,密码就会被设置成不使用,同用 set_unusable_password()。

  • check_password(raw_password)

检查密码是否正确。 给定的密码正确返回 True。

  • set_unusable_password()

设置user无密码。 不同于密码为空,如果使用 check_password(),则不会返回True。不保存AbstractBaseUser 对象。

  • has_usable_password()

如果设置了set_unusable_password(),返回False。

  • get_session_auth_hash()

返回密码字段的HMAC。

二、为 User 模型自定义管理器

继承自 BaseUserManager

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
from django.db import models
class UserManager(BaseUserManager):
    def _create_user(self, telephone, username, password, **kwargs):
        # self.model 等价于  User()
        user = self.model(telephone=telephone, username=username, **kwargs)
        # 密码需要加密,不能直接放在用户在保存
        user.set_password(password)
        user.save()
        return user
    def create_user(self,telephone,username,password,**kwargs):
        kwargs['is_superuser'] = False
        return self._create_user(telephone, username, password, **kwargs)

    def create_superuser(self, telephone, username, password, **kwargs):
        kwargs['is_superuser'] = True
        return self._create_user(telephone, username, password, **kwargs)

三、自定义用户和权限

Django 提供了 PermissionsMixin。这是一个抽象的类,可以为自定义用户模型中的类的层次结构中包含它。它提供所有 Django 权限类必须的方法和字段。

class User(AbstractBaseUser,PermissionsMixin):
    # 手机号 和 邮箱 是唯一
    telephone = models.CharField(max_length=11, unique=True)
    username = models.CharField(max_length=100)
    # 指定邮箱可以为空 默认不为空 创建用户时只传入了 username password
    email = models.EmailField(unique=True, null=True)
    # 是否激活
    is_active = models.BooleanField(default=True)
    # 0 代表未知,1 男 ;2 女
    gender = models.IntegerField(default=0)
    date_joined = models.DateTimeField(auto_now_add=True)
    is_staff = models.BooleanField(default=False)
    # USERNAME_FIELD 这个属性是以后在使用authenticate 进行验证的字段
    USERNAME_FIELD = 'telephone'
    # 这个属性是用来,以后在命令行中使用createsuperuser命令的时候,会让你输入的字段
    # 我们只用创建超级管理员的时候,就会让你输入 USERNAME_FIELD 指定的字段
    # 现在 USERNAME_FIELD 指定的字段是 telephone ,以及password 这个字段不写也会让你输入
    REQUIRED_FIELDS = ['username']
    # 以后给某个用户发送邮箱的时候,就会使用这个属性指定的字段的值来发送
    EMAIL_FIELD = 'email'
    # User() 会传给 UserManager() 保存在 model() 中
    objects = UserManager()

    def get_full_name(self):
        return self.username
    def get_short_name(self):
        return self.username

四、修改配置文件

覆盖默认的 User 模型。Django 允许通过修改 settings.py 文件中的 AUTH_USER_MODEL 设置覆盖默认的 User 模型,其值引用一个自定义的模型。

# AUTH_USER_MODEL 这个属性是 django 内置的,会主动到这个文件中查找这个属性,
# 如果找到了,那么就会使用这个属性指定的模型来作为 User 对象
# AUTH_USER_MODEL 这个属性是一个字符串,规则是 “appname.Modelname”
# app 下的哪个模型
# 如果设置了 AUTH_USER_MODEL,那么项目的 makemigrations 以及 migrate命令
# 必须要在设置完这些东西后再执行
AUTH_USER_MODEL = 'User'

本文分享自微信公众号 - 数据云团(SmartData),作者:云团小楠

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Django实战-Signals 信号量

    Django网络应用开发的5项基础核心技术包括模型(Model)的设计,URL 的设计与配置,View(视图)的编写,Template(模板)的设计和Form(...

    小团子
  • Django Rest Framework 限流(下)

    向认证一样Django进阶篇 Rest framework (五),在 utils 包中定义限流组件。

    小团子
  • Python进阶-GUI-目录树

    从当前目录开始,提供一个文件列表。双击列表中任意其它目录,就会使得工具切换到新目录中,用新目录中的文件列表代替旧文件列表。

    小团子
  • nodejs+express实现用户登录,注册以及退出操作

    先从用户注册说起吧,毕竟注册才能去数据库增加数据,然后在增加校验,本次先从注册===>登录===>退出这个层次顺序说起!接下来看一下用户注册!

    十月梦想
  • 『开发技巧』PyQt5入门教程

    PyQt5是一套来自Digia的Qt5应用框架和Python的粘合剂。支持Python2.x和Python3.x版本。本教程使用Pyhton 3。Qt库是最强大...

    小宋是呢
  • nodejs 轻量级http服务器

    小贝壳
  • Python全栈Day 20部分知识点

    def timmer(func): def wrapper(): print(func) func() retu...

    py3study
  • 美众议院提案禁止政府采购中企视频监控设备,海康威视回应

    新智元
  • 万宝盛华指出机器人将永久改变劳动力市场

    全球最大的人力资源公司之一万宝盛华集团(ManpowerGroup)发布了一份报告,详细介绍了机器人技术革命将如何永久改变劳动力市场。 该公司结合在瑞士达沃斯举...

    人工智能快报
  • Python面向对象设计和面向对象编程解析

    我们都知道Python是一门灵活度很高的语言,它可以面向过程,面向对象,那我们今天说说Python中的面向对象设计和面向对象编程的区别

    南山烟雨

扫码关注云+社区

领取腾讯云代金券