Django 自定义用户 VS 用户资料

2024-08-09 10:15:17 浏览数 (2)

Django是一个流行的Web框架,它提供了一套完整的用户认证系统,其中包括内置的User模型用于存储基本的用户信息,如用户名、密码等。然而,如果我们需要更详细的用户资料管理,比如添加更多的字段或者自定义验证规则,Django允许我们自定义用户模型。

1、问题背景

在 Django 1.5.1 中,我使用自定义用户,就像官方文档中描述的那样。我发现所有内容都存储在一个表中,即 auth_user 表。我的问题是,为什么最好将所有内容都放在一个大表中,而不是像 1.5 之前那样使用一个 user_profile 表来存储所有附加数据,并使用两个表?如果我们要为用户添加 20 个新信息字段,那么将所有内容都放在 auth_user 中似乎很奇怪。

我目前的情况是,我有一个类 MyUser(AbstractUser),它有两个附加字段 genderdate_of_birth,所以这样很好,但现在我想拥有更多其他信息(文本字段),比如“最喜欢的电影”、“最喜欢的书籍”、“爱好”、“五件不可缺少的东西”等,以便对我的用户有更多了解。所以我只是想知道我是否应该将这些信息放在 MyUser 类中,或者我是否应该定义一个 UserProfile 类?为什么?

2、解决方案

方案一:

当所有内容都放在一个表中时,数据库访问会更快。使用旧方法,您必须连接辅助表才能获取用户的全部信息。通常,当您看到一对一的关系时,最好将它们合并到一个表中。

但新的自定义用户模型还解决了另一个问题,即用户应该具有哪些属性?哪些属性对于您的应用程序至关重要?是否需要电子邮件?电子邮件是否还应该是用户登录的用户名?在引入此功能之前,您无法执行这些操作。

关于您有关将“爱好”等其他用户信息放在何处的问题,这确实取决于您查询/需要这些属性的频率。它们是否仅在用户的个人资料页面上?那么您可以将它们放在单独的表中,并且不会出现太多问题或性能下降。否则,最好将它们存储在与用户相同的表中。

方案二:

使用自定义用户模型时,您可以控制哪些字段包含在用户模型中。这为您提供了灵活性,以便根据应用程序的特定需求自定义用户模型。

例如,如果您希望用户能够添加个人资料图片,则可以在用户模型中添加一个字段来存储图片的 URL。您还可以添加一个字段来存储用户的出生日期或性别。

如果您希望将用户数据存储在单独的表中,则可以创建包含这些数据的用户资料模型。这可以使您的用户模型更精简,同时为您提供灵活的存储其他用户数据的方式。

代码示例:

代码语言:javascript复制
# 自定义用户模型
​
class MyUser(AbstractUser):
    gender = models.CharField(max_length=10, choices=[('M', 'Male'), ('F', 'Female')])
    date_of_birth = models.DateField()
​
# 用户资料模型
​
class UserProfile(models.Model):
    user = models.OneToOneField(MyUser, on_delete=models.CASCADE)
    favorite_movies = models.CharField(max_length=255)
    favorite_books = models.CharField(max_length=255)
    hobbies = models.CharField(max_length=255)
    five_things_i_could_not_live_without = models.CharField(max_length=255)

您还可以使用 Django 的信号来同步用户模型和用户资料模型。这将确保当用户模型更新时,用户资料模型也会更新。

代码语言:javascript复制
@receiver(post_save, sender=MyUser)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)
​
@receiver(post_save, sender=MyUser)
def save_user_profile(sender, instance, **kwargs):
    instance.userprofile.save()

这样您就可以在 Django 中使用自定义用户模型和用户资料模型来存储用户数据了。

0 人点赞