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

查看所有标签

猜你喜欢:

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

深入浅出MFC (第二版)

深入浅出MFC (第二版)

侯俊杰 / 华中科技大学出版社 / 2001-1 / 80.00元

《深入浅出MFC》分为四大篇。第一篇提出学习MFC程序设计之前的必要基础,包括Widnows程序的基本观念以及C++的高阶议题。“学前基础”是相当主观的认定,但作者是甚于自己的学习经验以及教学经验,其挑选应该颇具说服力。第二篇介绍Visual C++整合环境开发工具。此篇只是提纲挈领,并不企图取代Visual C++使用手册;然而对于软件使用的老手,此篇或已足以帮助掌握Visual C++整合环境......一起来看看 《深入浅出MFC (第二版)》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

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

Markdown 在线编辑器