内容简介: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中有两种现代方法可以创建自定义用户模型: AbstractUser
和 AbstractBaseUser
。这里推荐 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_profile
和 save_user_profile
方法调用。
这个方案不需要修改 AUTH_USER_MODEL
。由于这个方案会对模型添加关联关系,所以可能在查询时候会出发一个额外查询,但大多数情况下都不会触发。
由于定义的信号,所以在模型的创建和修改时,一定会触发额外的查询的。
以上所述就是小编给大家介绍的《如何扩展 Django 的用户模型》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 深入理解JUnit 5的扩展模型
- 使用 laravel-repository 扩展包实现对模型类操作的封装
- 谷歌开源 GPipe,训练更大模型、不调整超参扩展性能
- 谷歌开源 GPipe,训练更大模型、不调整超参扩展性能
- 百度将高性能计算引入深度学习:可高效实现模型的大规模扩展(附资源)
- 数据驱动型的 IoT 体系架构设计,第 3 部分: 高级数据抽象模型下 IoT 的次级数据扩展
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
区块链核心算法解析
【瑞士】Roger Wattenhofer(罗格.瓦唐霍费尔) / 陈晋川、薛云志、林强、祝庆 / 电子工业出版社 / 2017-8 / 59.00
《区块链核心算法解析》介绍了构建容错的分布式系统所需的基础技术,以及一系列允许容错的协议和算法,并且讨论一些实现了这些技术的实际系统。 《区块链核心算法解析》中的主要概念将独立成章。每一章都以一个小故事开始,从而引出该章节的内容。算法、协议和定义都将以形式化的方式描述,以便于读者理解如何实现。部分结论会在定理中予以证明,这样读者就可以明白为什么这些概念或算法是正确的,并且理解它们可以确保实现......一起来看看 《区块链核心算法解析》 这本书的介绍吧!