Django初窥门径-自定义用户模型

news2024/11/25 10:30:23

前言

自定义用户模型在Django应用中是一个重要的话题,它涉及到如何根据您的项目需求以及特定的用户身份验证和授权需求来调整用户模型。在以下前言中,我将讲述为什么自定义用户模型是如此重要以及其潜在的优势:

随着Web应用的不断发展,用户身份认证和授权的需求也变得越来越多样化。在默认情况下,Django提供了一个名为django.contrib.auth.models.User的用户模型,它包含了常见的用户属性和方法,但不一定满足所有项目的要求。因此,自定义用户模型成为了一个必要的选择,它允许我们根据项目的具体需求来调整用户模型。

自定义用户模型的优势无处不在。首先,它使我们能够添加、修改或删除用户模型中的字段,以适应项目的特定数据。您可以为用户模型添加新的属性,如个人资料信息、头像、联系方式等,从而更好地满足项目需求。其次,自定义用户模型也允许您更好地集成社交媒体登录、第三方身份验证等功能,以提供更多的用户便利性。

此外,自定义用户模型还可以增强安全性。通过添加自定义字段,您可以更好地管理密码策略,实施多因素身份验证,记录安全审计日志等。最重要的是,自定义用户模型为您提供了更大的灵活性,以适应未来的项目需求和扩展。

总之,自定义用户模型不仅仅是一种实现特定项目需求的手段,更是提高Web应用的灵活性、安全性和可维护性的重要工具。在接下来的文章中,我们将深入探讨如何创建和使用自定义用户模型,以及它如何帮助我们构建更强大的Django应用。

Django用户模型

Django用户模型是Django框架的一个关键组件,用于处理用户认证和用户管理的任务。它为您提供了一种便捷的方式来创建、注册、登录和管理用户,同时也支持用户自定义以满足特定项目需求。

内置用户模型

Django提供了一个内置的用户模型 (django.contrib.auth.models.User),其中包含以下常见用户属性:

  • 用户名
  • 密码
  • 电子邮件地址
  • 名字
  • 姓氏

您可以轻松地在Django项目中启用这个内置用户模型并使用它来实现用户认证功能。

用户认证

Django用户模型简化了用户认证流程。以下是一些与用户认证相关的功能:

  • 用户注册
  • 用户登录
  • 用户注销
  • 密码重置
  • 用户会话管理

Django提供了内置视图和装饰器,以帮助您轻松实现这些功能。

用户自定义

如果需要更多用户属性或者用户模型的不同结构,您可以自定义用户模型。通常的做法是创建一个自定义用户模型,继承自 AbstractUser,然后为其添加额外的字段,以满足项目的需求。

from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    # 自定义字段
    age = models.PositiveIntegerField()

用户认证后端

Django允许您使用不同的用户认证后端。默认情况下,Django使用用户名和密码进行认证,但您可以实现其他认证方法,如社交媒体登录、LDAP认证等。

权限和组

Django用户模型也支持用户权限和用户组的管理。您可以为用户分配不同的权限,并将用户组用于更好地管理这些权限。

用户管理界面

Django提供了一个内置的管理界面,可用于管理用户、组和权限,使用户管理变得更加便捷。
这些是Django用户模型的一些重要方面,它们可用于构建强大的用户认证和管理系统,同时也具备灵活性,以满足不同项目的需求。

创建自定义模型

创建一个account应用

python manage.py startapp account

创建自定义用户管理器

由于我们需要对默认用户模型的字段进行增删,所以需要自己实现一个用户管理器来管理我们的自定义模型。

class UserManager(BaseUserManager):
    """用户管理器"""
    use_in_migrations = True

    def _create_user(self, username, email, password, **extra_fields):
        if not username:
            raise ValueError('The given username must be set')
        email = self.normalize_email(email)
        username = self.model.normalize_username(username)
        user = self.model(username=username, email=email, password=password, **extra_fields)
        user.save(using=self._db)
        return user

    def create_user(self, username, email=None, password=None, **extra_fields):
        extra_fields.setdefault('is_active', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(username, email, password, **extra_fields)

    def create_superuser(self, username, email, password, **extra_fields):
        extra_fields.setdefault('is_active', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_active') is not True:
            raise ValueError('Superuser must have is_active=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')
        return self._create_user(username, email, password, **extra_fields)
特征自定义管理器 (UserManager)默认管理器 (django.contrib.auth.models.UserManager)
创建用户方法提供 _create_user, create_usercreate_superuser 方法,允许根据特定需求创建用户对象。提供 create_usercreate_superuser 方法,用于创建普通用户和超级用户,但可能不够灵活以满足特定需求。
默认值设置允许设置特定的默认值,如 is_activeis_superuser,以确保创建的用户对象具有所需属性。提供一组默认值,通常创建的用户是活动的和非超级用户,可能需要进一步修改属性。
私有方法包含 _create_user 方法,它是私有的,不直接暴露给外部调用,而是通过公共方法 create_usercreate_superuser 访问。默认管理器没有私有方法,所有方法都是公共的,可以直接调用。
自定义性提供更灵活的方式来定义用户创建逻辑,包括额外字段的处理和验证。提供通用的用户创建方法,适用于大多数情况,但可能不满足特定项目的自定义需求。
用途适用于需要特定用户创建逻辑和更多控制的项目。适用于大多数一般情况下的项目,需要快速创建用户对象。

通过上述比较,您可以看到自定义管理器和默认管理器之间的一些关键区别,自定义管理器更适合在需要更多控制和自定义的项目中使用。默认管理器适用于一般情况下,可以快速创建用户对象,而自定义管理器则提供了更多的弹性和灵活性。

创建抽象用户模型

创建自定义权限混合模型

#!/usr/bin/python
# -*- coding: utf-8 -*-
from django.contrib.auth.models import _user_has_perm, _user_has_module_perms
from django.db import models


class PermissionsMixin(models.Model):
    """超级用户权限混合模型"""
    is_superuser = models.BooleanField('超级用户状态', default=False, help_text='指明该用户缺省拥有所有权限。')

    class Meta:
        abstract = True

    def has_perm(self, perm, obj=None):
        """
        Return True if the user has the specified permission. Query all
        available auth backends, but return immediately if any backend returns
        True. Thus, a user who has permission from a single auth backend is
        assumed to have permission in general. If an object is provided, check
        permissions for that object.
        """
        # Active superusers have all permissions.
        if self.is_superuser:
            return True

        # Otherwise we need to check the backends.
        return _user_has_perm(self, perm, obj)

    def has_module_perms(self, app_label):
        """
        Return True if the user has any permissions in the given app label.
        Use simlar logic as has_perm(), above.
        """
        # Active superusers have all permissions.
        if self.is_superuser:
            return True

        return _user_has_module_perms(self, app_label)

PermissionsMixin 是一个抽象模型,用于将超级用户的权限特性添加到用户模型中。我们的自定义PermissionsMixin 与Django默认的用户模型(User)之间的主要区别在于权限管理。

特征PermissionsMixin默认的 User 模型
超级用户标识字段(is_superuser)存在,并且是一个布尔字段,用于表示用户是否是超级用户。默认情况下,用户不是超级用户。默认 User 模型中也存在 is_superuser 字段,但在创建用户时通常不会指定该字段,它会默认为 False
检查用户权限的方法(has_perm)PermissionsMixin 提供了 has_perm 方法,用于检查用户是否具有指定的权限。如果用户是超级用户,直接返回 True默认 User 模型中也有 has_perm 方法,但其行为可能会因所使用的身份验证后端而异。
检查应用程序权限的方法(has_module_perms)PermissionsMixin 提供了 has_module_perms 方法,用于检查用户是否在给定应用程序标签中具有任何权限。默认 User 模型中没有 has_module_perms 方法,检查应用程序权限通常需要自己实现。
使用场景适用于需要超级用户权限相关功能的应用,可以与自定义用户模型一起使用。适用于一般情况下的应用,通常不需要额外的超级用户权限功能。
默认值设置is_superuser 默认为 False,表示用户不是超级用户。需要在用户创建时手动设置为 Trueis_superuser 默认为 False,在创建用户时通常不需要显式设置。
帮助文本提供了帮助文本,解释了 is_superuser 字段的作用,即指明该用户是否默认拥有所有权限。默认 User 模型中的 is_superuser 字段通常没有相应的帮助文本。

总的来说,PermissionsMixin 旨在扩展用户模型以添加超级用户权限相关的功能,如检查用户是否具有特定权限和应用程序权限。默认的 User 模型是通用的,适用于大多数一般情况,但不包括额外的超级用户权限管理功能。可以根据项目需求选择是否使用 PermissionsMixin 或默认的 User 模型。

创建自定义校验器

#!/usr/bin/python
# -*- coding: utf-8 -*-
from django.core import validators
from django.utils.deconstruct import deconstructible


@deconstructible
class UsernameValidator(validators.RegexValidator):
    """用户名校验"""
    regex = r'^[a-zA-Z0-9_.]{4,16}$'
    message = '请输入4-16位字母数字以及下划线和点的组合'
    flags = 0

我们创建了一个自定义的用户名校验器,该校验器通过继承 validators.RegexValidator 并使用 @deconstructible 装饰器来创建一个可序列化的自定义校验器。

创建抽象用户模型

class AbstractUser(AbstractBaseUser, PermissionsMixin):
    """抽象用户模型"""
    username_validator = UsernameValidator()
    username = models.CharField('用户名', max_length=150, unique=True, validators=[username_validator],
                                help_text='必填。150个字符或者更少。包含字母,数字和仅有的/./+/-/_符号。',
                                error_messages={
                                    'unique': '已存在一位使用该名字的用户。',
                                })
    email = models.EmailField('电子邮件地址', unique=True, blank=False, null=False)
    is_active = models.BooleanField('有效', default=False, help_text='指明用户是否被认为是活跃的。以反选代替删除帐号。')
    # 需要使用 Django Admin的同学必须添加该字段,不然访问会报错
    is_staff = models.BooleanField('员工', default=True)
    date_joined = models.DateTimeField('加入日期', default=timezone.now)

    objects = UserManager()

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    class Meta:
        verbose_name = '用户'
        verbose_name_plural = verbose_name
        abstract = True
关键点描述
类的名称AbstractUser - 这是一个抽象用户模型。
继承关系继承自 AbstractBaseUserPermissionsMixin,具备身份认证和权限管理的功能。
username_validator包含了用户名校验器 UsernameValidator,用于验证用户名是否符合指定格式要求。
username 字段表示用户的用户名,包含帮助文本和错误消息,唯一且不可为空。
email 字段表示用户的电子邮件地址,唯一且不可为空。
is_active 字段表示用户的活跃状态,默认为非活跃状态。
date_joined 字段表示用户的加入日期,使用 timezone.now 作为默认值。
objects用户管理器,通常是一个自定义的用户管理器,用于管理用户对象。
EMAIL_FIELD用户模型中用于电子邮件地址的字段名称。
USERNAME_FIELD用户模型中用于用户名的字段名称。
REQUIRED_FIELDS包含了必填字段列表,包括了电子邮件地址。
Meta定义了一些元数据,如用户模型的名称、复数形式名称,以及将其设置为抽象模型。
用途用作其他用户模型的基础,提供了身份认证和权限管理的功能,可用于创建自定义用户模型。

这个抽象用户模型提供了一个基础,可用作其他用户模型的基础。其他用户模型可以继承此抽象用户模型,以获得身份认证和权限管理的功能,并根据需要扩展字段和行为。这样,我们可以轻松创建满足特定项目需求的用户模型。

创建用户模型

class User(AbstractUser):
    avatar = models.URLField('头像', null=True)
    last_login_ip = models.GenericIPAddressField(null=True)

    def __str__(self):
        return self.username

    class Meta:
        ordering = ['-last_login']
关键点描述
类的名称User - 这是一个自定义用户模型,继承自Django内置的AbstractUser
继承关系继承自AbstractUser,继承了AbstractUser中的字段和方法,并允许添加自定义字段和方法。
自定义字段- avatar字段:用于存储用户的头像URL,类型为URLField,允许为空。
- last_login_ip字段:用于存储用户的上次登录IP地址,类型为GenericIPAddressField,也允许为空。
__str__ 方法定义了对象的字符串表示,返回用户的用户名作为字符串表示。
Meta- ordering属性:定义查询结果的默认排序方式,按last_login字段降序排序,最后登录的用户排在前面。
用途用作自定义用户模型,允许在Django应用中使用,并添加额外的字段和方法来满足特定项目的需求。

这个自定义用户模型允许我们创建具有额外功能的用户对象,例如存储用户头像和上次登录IP地址,同时继承了Django内置用户管理的功能,如身份认证和权限管理。可以根据具体项目的需求,创建自定义用户模型来满足特定的功能和字段要求。

应用自定义用户模型

AUTH_USER_MODEL = 'account.User'

AUTH_USER_MODEL 是一个Django设置,用于指定自定义用户模型的路径。AUTH_USER_MODEL 被设置为 ‘account.User’,表示自定义用户模型位于account应用中的User模型。

通过设置AUTH_USER_MODEL,告诉Django使用指定的用户模型来处理身份验证和用户相关的操作,而不是使用默认的django.contrib.auth.models.User模型。这允许我们自定义用户模型,以满足项目的特定需求。

在使用自定义用户模型时,需要确保将AUTH_USER_MODEL设置在项目的设置文件中,以便Django知道要使用哪个用户模型。这通常在项目的settings.py文件中设置。

在后续开发中,我们使用get_user_model() 用于替代硬编码用户模型的引用,以提高代码的灵活性和可维护性。在使用自定义用户模型时,它有助于确保代码与用户模型的更改保持兼容。比如:

User = get_user_model()

处理用户注册时填写的密码

#!/usr/bin/python
# -*- coding: utf-8 -*-
from django.contrib.auth import get_user_model
from django.db.models import signals
from django.dispatch import receiver

User = get_user_model()


@receiver(signals.post_save, sender=User)
def create_user(sender, instance=None, created=False, **kwargs):
    """
    创建用户信号量
    """
    if created:
        """创建用户时将明文密码改成加密格式"""
        password = instance.password
        instance.set_password(password)
        instance.save()
关键点描述
获取用户模型(get_user_model()使用 get_user_model() 函数来获取当前项目中配置的用户模型,确保与项目中使用的用户模型保持一致。
信号接收器装饰器(@receiver使用 @receiver 装饰器注册信号接收器,指定了接收 post_save 信号,表示在保存用户对象后触发信号,同时指定了信号的发送者为 User 模型。
create_user 函数信号接收器的处理函数,用于处理 post_save 信号。
- created 参数用于判断用户对象是否是新创建的,如果 createdTrue,表示用户是新创建的。
- 密码加密在处理函数中,从用户实例中获取明文密码,然后使用 set_password 方法将其转换为加密格式,最后保存用户实例以将加密后的密码存储到数据库中。
作用该信号接收器的作用是在创建用户时,自动将明文密码转换为加密格式并保存到数据库中,以提高用户密码的安全性。

这个信号量用于确保用户的密码在创建时自动得到加密处理,而不以明文形式存储在数据库中。通常与自定义用户模型一起使用,以确保密码安全性的提高。

我们需要在apps.py中注册这个信号量:

from django.apps import AppConfig


class AccountConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'account'

    def ready(self):
        from . import signals

ready 方法是应用配置的一个特殊方法,它在Django启动时自动执行。在这里,它导入了应用内的signals模块,以便应用的信号接收器可以注册并在应用启动时生效。

此时,千万不要忘了在配置文件里注册我们的account应用

INSTALLED_APPS = [
   ...
    'account.apps.AccountConfig',
    ...
]

重新初始化数据库

由于我们更改了用户模型,对数据库影响较大,应用到数据库的时候可能会报错,所以建议删掉所有表重新初始化。

python manage.py makemigrations
python manage.py migrate

模型的更改应用到数据库后,我们就可以生成超级用户了:

python manage.py createsuperuser

在这里插入图片描述
由上图可以看出,我们已经应用新的用户模型生成了数据库表,并且创建了超级用户。

结语

在本文中,我们探讨了Django中的用户模型、信号接收器以及数据库迁移。我们了解了如何自定义用户模型以满足特定项目需求,如何使用信号接收器处理各种操作,以及如何使用迁移来管理数据库模式的变更。这些都是Django中的关键概念,有助于构建强大的Web应用。希望本文能帮助您更深入地理解这些概念,并在您的项目中有所应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1179545.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

只改一行语句,锁这么多?

👉导读 这篇文章我想来聊聊 MySQL 的锁是怎么加上的,为啥想聊这个呢?主要是因为业务中我们或多或少都会使用到锁,毕竟锁是保障我们数据安全性的关键法宝。但是由于不了解原理,往往可能导致我们在”刻意“或者”无意“的…

JavaScript从入门到精通系列第三十篇:详解JavaScript中的正则表达式语法

文章目录 前言 1:概念回顾 2:正则表达式 一:正则表达式 1:正则表达式字面量 2:检查是否有a或者b 3:检查是否有字母 4:检查是否有abc/aec/afc 5:检查除了ab 大神链接&#x…

Python教程:打印自己的名字

要打印的名字是:PYTHON …######… …#…#… …######… …#… …#… …#…#… …#…#… …##… …##… …##… …######… …##… …##… …##… …##… …#…#… …#…#… …######… …#…#… …#…#… …######… …#…#… …#…#… …#…#… …######… ……

【Spring实战——构建Spring Web应用程序】1.10 处理表单

引言 Web应用功能 ○ 提供内容 ○ 用户填写表单 ○ 提交数据 Spring MVC的控制器提供了 ○ 处理表单展示 ○ 用户提交数据的支持 在Spittr应用中,需要一个注册表单供新用户使用。SpitterController是一个新的控制器,目前只有一个请求处理方法用于展示…

LInux-0.11

文章目录 前言学习资料正文 前言 B站视频链接 linux 0.11 内核代码 学习资料 正文 一个山区512字节

稀土/铜催化剂电催化CO2制C2+或CH4

在电化学CO2还原反应(CO2RR)中,合理调控反应途径以生成所需产物是最重要的挑战之一。基于此,中国科学院化学研究所韩布兴院士和朱庆宫研究员等人报道了一系列稀土-铜混合相催化剂,通过调整催化剂的组成和结构&#xff…

Nodejs的安装以及配置(node-v12.16.1-x64.msi)

Nodejs的安装以及配置 1、安装 node-v12.16.1-x64.msi点击安装,注意以下步骤 本文设置nodejs的安装的路径:D:\soft\nodejs 继续点击next,选中Add to PATH ,旁边的英文告诉我们会把 环境变量 给我们配置好 当然也可以只选择 Nod…

工业自动化工厂PLC远程控制网关物联网应用

远程控制网关在工厂自动化领域中起到了至关重要的作用,特别是在工厂PLC数据通讯方面。它充当着数据传输的桥梁,连接了工厂中的各类设备和系统,实现了远程监控和控制的功能。本文将详细介绍远程控制网关在工厂PLC数据通讯中的应用。 远程控制网…

Hadoop知识点全面总结

文章目录 什么是HadoopHadoop发行版介绍Hadoop版本演变历史Hadoop3.x的细节优化Hadoop三大核心组件介绍HDFS体系结构NameNode介绍总结 SecondaryNameNode介绍DataNode介绍DataNode总结 MapReduce介绍分布式计算介绍MapReduce原理剖析MapReduce之Map阶段MapReduce之Reduce阶段 实…

Langchain-Chatchat-win10本地安装部署成功笔记(CPU)

Langchain-Chatchat(原Langchain-ChatGLM)基于 Langchain 与 ChatGLM 等语言模型的本地知识库问答 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM) QA app with langchain。 开源网址:https:…

leetcode周赛 第 370 场周赛

2923. 找到冠军 I 一场比赛中共有 n 支队伍&#xff0c;按从 0 到 n - 1 编号。 给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 < i, j < n - 1 且 i ! j 的所有 i, j &#xff1a;如果 grid[i][j] 1&#xff0c;那么 i 队比 j 队 强 &…

第五章:java构造方法与对象创建

系列文章目录 文章目录 系列文章目录前言一、构造方法&#xff08;构造器&#xff09;二、对象创建流程总结 前言 构造方法由程序自动调用&#xff0c;完成对象初始化。 一、构造方法&#xff08;构造器&#xff09; 构造方法又叫构造器(constructor)&#xff0c; 是类的一种…

将字符串转换为日期型对象date.fromisoformat(str)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将字符串转换为日期型对象 date.fromisoformat(str) 选择题 下列代码执行后&#xff0c;变量d的数据类型是? s 2023-11-01 d date.fromisoformat(s) print(f"【显示】s {s}") p…

大数据毕业设计选题推荐-家具公司运营数据分析平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

SLAM从入门到精通(车道线检测)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于slam而言&#xff0c;大家一般想到的就是去通过传感器找特征点&#xff0c;进而借助于特征点去定位机器人的位置。但是对于用户或者厂家来说&a…

Linux常用命令——cd命令

在线Linux命令查询工具 cd 切换用户当前工作目录 补充说明 cd命令用来切换工作目录至dirname。 其中dirName表示法可为绝对路径或相对路径。若目录名称省略&#xff0c;则变换至使用者的home directory(也就是刚login时所在的目录)。另外&#xff0c;~也表示为home directo…

LabVIEW开发多速率实时混合仿真

LabVIEW开发多速率实时混合仿真 混合仿真是一种子结构技术&#xff0c;通过将数值建模的优点与实验测试的优点相结合来模拟感兴趣的结构。模拟结构的其余部分特别令人感兴趣&#xff0c;因此可以进行物理复制&#xff0c;以揭示粘弹性、屈曲、速率相关特性或其他非线性效应的影…

微信小程序文件上传wx.uploadFile

网页版查看了一下负载要求是这样 wx.uploadFile({url: ${wx.getStorageSync(apiUrl)}//sysFileInfo/upload?token${wx.getStorageSync(token)}, // 仅为示例&#xff0c;非真实的接口地址filePath: files[0].url,name: file,formData: {secretFlag: Y },success: (res) > {…

Android 11.0 framework层实现app默认全屏显示

1.前言 在11.0的系统rom定制化开发中,在对于第三方app全屏显示的功能需求开发中,需要默认app全屏显示,针对这一个要求,就需要在系统启动app 的过程中,在绘制app阶段就设置全屏属性,接下来就实现这个功能 效果图如下: 2.framework层实现app默认全屏显示的核心类 framewo…

数据跨领域应用实例—公路数据应用场景(一)

2023年10月25日&#xff0c;国家数据局正式揭牌。标志着我国数据基础制度正在不断完善&#xff0c;数据资源使用水平稳额步提升&#xff0c;数据要素市场将进入发展快车道。当前&#xff0c;数字经济已成为我国经济高质量发展的新动能&#xff0c;国家数据局的成立&#xff0c;…