如何扩展 Django 的用户模型

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

内容简介:Django 内置的通常我们需要存储更多用户相关的数据,内置的模型已无法满足。我们需要对它进行扩展。这是最推荐的一个方案了。正如官方

起步

Django 内置的 用户模型 提供了包括身份认证等非常棒的功能,在大多数情况下开箱即用,节省了大量的开发和测试的工作。

通常我们需要存储更多用户相关的数据,内置的模型已无法满足。我们需要对它进行扩展。

自定义模型

这是最推荐的一个方案了。正如官方 Django文档 强烈建议为新项目使用自定义用户模型。

If you're starting a new project, it's highly recommended to set up a custom user model, even if the default User model is sufficient for you. 
(如果您要开始一个新项目,强烈建议您设置自定义用户模型,即使默认User模型已经足够。)

而对于已经使用内置模型也有办法扩展,后续再讲。

AbstractUser 还是 AbstractBaseUser ?

在Django中有两种现代方法可以创建自定义用户模型: AbstractUserAbstractBaseUser 。这里推荐 AbstractUser ,它是 AbstractBaseUser 的子类,提供了较为完整的用户模型,包含字段,作为抽象类,以便您可以继承它并添加自己的配置文件字段和方法。而 AbstractBaseUser 只包含身份验证功能,不包含其他实际字段,若使用它则需要更多的工作,说真的,除非你确实有需要,否则不要乱用它。

创建用户模型

创建个应用来处理用户模型 python manage.py startapp users ,在 users.models 中定义模型:

from django.db import models
from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    birth_date = models.DateField(null=True, blank=True)

    def __str__(self):
        return self.username

这个模型是在保持内置 User 字段和功能下进行的扩展,能够存储更多用户相关的数据。然后在 settings.py 中指定:

AUTH_USER_MODEL = 'users.CustomUser'

扩展内置的用户模型

再次强调,还是推荐使用自定义的模型。但如果很不幸,项目用了内置模型并运行了一段时间,那该怎么扩展呢?办法也是有的。

1. 使用代理模型扩展用户模型

这是扩展现有用户模型的侵入性较小的方法。这种策略不会有任何缺点。但它在很多方面都非常有限。

from django.contrib.auth.models import User
class MyUser(User):
    class Meta:
        proxy = True

    def get_xxxx(self):
        return ''

使用 proxy = True 不会新生成数据表,却能给予模型更多操作,对原有的功能几乎是没有影响的。

同样需要在 settings.py 中设置 AUTH_USER_MODEL ,但由于认证模型的修改,在 migrate 时可能会报错:

raise ValueError("\n".join(error.msg for error in errors))
ValueError: The field admin.LogEntry.user was declared with a lazy reference to 'accounts.user', but app 'accounts' doesn't provide model 'user'.

别担心,这是原先的模型依然依赖于内置模型而不是代理模型。清空表 django_migrations 并执行 python manage.py migrate --fake 即可。

这种方法优点十分明显,但缺点就是不能存储额外数据。(哦?也许可以在操作中将数据存于其他表?)

2. 使用一对一链接扩展用户模型

对于扩展内置用户模型而言,这个方案比较普遍,因为它能存储额外信息和添加新的操作。

from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    location = models.CharField(max_length=30, blank=True)
    birth_date = models.DateField(null=True, blank=True)

接下来就是这个方案神奇的地方了,我们将通过 信号 来自动创建和更新模型:

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    location = models.CharField(max_length=30, blank=True)
    birth_date = models.DateField(null=True, blank=True)

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

基本上,每当发生保存事件时,都会通过 post_save 信号将用户模型 create_user_profilesave_user_profile 方法调用。

这个方案不需要修改 AUTH_USER_MODEL 。由于这个方案会对模型添加关联关系,所以可能在查询时候会出发一个额外查询,但大多数情况下都不会触发。

由于定义的信号,所以在模型的创建和修改时,一定会触发额外的查询的。


以上所述就是小编给大家介绍的《如何扩展 Django 的用户模型》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

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

Kotlin实战

Kotlin实战

【美】Dmitry Jemerov(德米特里·詹莫瑞福)、【美】 Svetlana Isakova(斯维特拉娜·伊凡诺沃) / 覃宇、罗丽、李思阳、蒋扬海 / 电子工业出版社 / 2017-8 / 89.00

《Kotlin 实战》将从语言的基本特性开始,逐渐覆盖其更多的高级特性,尤其注重讲解如何将 Koltin 集成到已有 Java 工程实践及其背后的原理。本书分为两个部分。第一部分讲解如何开始使用 Kotlin 现有的库和API,包括基本语法、扩展函数和扩展属性、数据类和伴生对象、lambda 表达式,以及数据类型系统(着重讲解了可空性和集合的概念)。第二部分教你如何使用 Kotlin 构建自己的 ......一起来看看 《Kotlin实战》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

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

HEX CMYK 互转工具