如何扩展 Django 的用户模型

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

内容简介: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 的用户模型》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

破茧成蝶:用户体验设计师的成长之路

破茧成蝶:用户体验设计师的成长之路

刘津、李月 / 人民邮电出版社 / 2014-7 / 69.00

市面上已经有很多专业的用户体验书籍,但解决用户体验设计师在职场中遇到的众多现实问题的图书并不多见。本书从用户体验设计师的角度出发,系统地介绍了其职业生涯中的学习方法、思维方式、工作流程等,覆盖了用户体验设计基础知识、设计师的角色和职业困惑、工作流程、需求分析、设计规划和设计标准、项目跟进和成果检验、设计师职业修养以及需要具备的意识等,力图帮助设计师解决在项目中遇到的一些常见问题,找到自己的职业成长......一起来看看 《破茧成蝶:用户体验设计师的成长之路》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

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

Markdown 在线编辑器