如何更改默认的Django用户模型以适应我的需求?

14
默认的Django的用户模型有一些字段和验证规则,我并不需要。我希望尽可能简化注册流程,即要求电子邮件、用户名或电话号码 - 所有这些都是唯一的,因此可以作为用户标识符。
我也不喜欢Django用户模型中验证的默认字符集。我想允许任何字符 - 为什么不呢?
我之前使用过user-profile django应用程序来为用户添加个人资料 - 但这次我宁愿使类最小化。但我仍然想使用类,因为它为我提供了一个易于只限于登录用户使用网站部分的简单方法。
我该如何做?
5个回答

10

不必直接修改User类或进行子类化,您也可以重新利用现有字段。

对于一个网站,我将"first_name"字段用作用户的“公开显示名称”,并将其slugify版本放入“username”字段中(用于URL)。我编写了一个自定义身份验证后端,允许人们使用其“公共名称”或电子邮件地址登录,并在注册时强制执行两者的唯一性。这与其他可重用的应用程序相容,并不会引入额外的表或查询。

对于另一个网站,我根本不想要用户名,只想要唯一的电子邮件地址。为了满足Django需要唯一用户名的要求,我只需哈希电子邮件地址并将其用作用户名(您必须对哈希进行base64编码以将其压缩到30个字符以下)。自定义身份验证后端允许使用电子邮件登录。

如果向后兼容不是问题,我很想看到django.contrib.auth和用户模型做出更灵活的改进。但在当前的限制条件下,您可以通过一些创意来实现很多东西。


有没有想法如何构建用电子邮件登录的身份验证后端? - kender
看看这个代码片段,让你开始:http://www.djangosnippets.org/snippets/74/。一定要阅读评论,因为第二个评论中的代码比片段中的代码更好,并且在评论中提出了许多其他相关问题,你需要记住。 - Carl Meyer

7

我误读了问题。希望这篇文章对其他人有所帮助。

#in models.py
from django.db.models.signals import post_save  

class UserProfile(models.Model):  
    user = models.ForeignKey(User)  
    #other fields here

    def __str__(self):  
          return "%s's profile" % self.user  

     def create_user_profile(sender, instance, created, **kwargs):  
        if created:  
           profile, created = UserProfile.objects.get_or_create(user=instance)  

post_save.connect(create_user_profile, sender=User) 

#in settings.py
AUTH_PROFILE_MODULE = 'YOURAPP.UserProfile'

每次创建用户时,如果已经创建,则会创建一个用户配置文件。您随后可以使用。
  user.get_profile().whatever

以下是来自文档的更多信息:

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

这个链接提供了有关在Django中存储用户附加信息的详细信息。

7
Django用户模型的结构非常合理。 例如,您真的不希望用户名中出现任意字符,并且有方法可以实现电子邮件地址登录,而无需对基本模型进行修改。
为了简单地存储关于用户帐户的其他信息,Django支持用户配置文件的概念。 虽然您不需要依赖内置支持来处理此操作,但这是一种通常遵循的约定,并且它将允许您与在网络上漂浮的可重复使用的Django应用程序相互配合。 有关更多信息,请参见此处
如果您想实际修改核心User模型,同时还要“友好地协作”可重复使用的应用程序,则会打开一个小小的潘多拉魔盒。 开发人员对核心库的结构做出基本假设,因此任何更改都可能导致意外的破坏。 尽管如此,您可以monkeypatch更改基本模型,或者在本地分支一个Django的拷贝。 我建议后者不要使用,只有你知道自己在干什么时才推荐使用前者。

6
Django的用户模型在结构上设计得很合理,如果您正在构建一个网站,它将是一个合理的用户模型,满足特定的需求。但是作为框架的核心用户抽象,它还有一些需要改进的灵活性。 - Carl Meyer
2
我同意一个更可插拔的认证系统会更理想。 - Daniel Naab

0

有很多方法可以做到这一点,但以下是我会采取的方法:允许用户输入电子邮件、用户名(必须包含至少一个字母且不含@符号)或手机号码。然后,在验证时:

  1. 检查是否存在@。如果是,则将其设置为用户的电子邮件,适当地进行哈希处理,并将其设置为他们的用户名。
  2. 检查它是否只包含数字、破折号和+。然后,剥离适当的字符并将其存储为手机号码和用户名(如果您将手机号码存储在另一个模型中以供短信等用途)。
  3. 如果都不是,则将其设置为用户名。

我还会在登录时类似地验证用户/电话/电子邮件字段,并查找适当的位置,以便如果用户使用其手机号码注册,然后更改其用户名(出于其他目的),他们仍然可以使用其手机号码登录。


0

如果你致力于避免已经指出的基于配置文件的自定义,那么你就会面临一个小困境,但这个困境实际上有两种解决方案:

  1. 按照 Daniel 的建议更改 User 模型本身。
  2. 编写一个自定义的 CustomUser 类,继承 User 或者复制它的功能。

后一种建议意味着您需要手动实现一些 User 自动执行的功能,但我想知道是否真的像听起来那样糟糕,特别是如果您的项目处于起步阶段。你只需要重写一些中间件类和一些装饰器。

当然,我认为这并不能带给你任何 1 所不能提供的好处,除非你的项目在更新 django 后不会破坏。这可能避免一些与其他应用程序的兼容性问题,但我猜问题还是存在的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接