【问题标题】:Email as username in Django电子邮件作为 Django 中的用户名
【发布时间】:2011-04-02 14:23:50
【问题描述】:

好的,这个对于每个使用 Django 并且经常被新手问到的人来说是很明显的,但是我想澄清一下并讨论是否有其他方法可以做到这一点。现在最普遍和最方便的方法是将电子邮件存储在用户名字段中,因为 Django 1.2 允许使用“@”、“_”和“-”字符,但这种方式存在以下问题:

  1. 最糟糕的是:用户名字段受max_length=30 属性的限制,这对于电子邮件来说太小了。即使您覆盖表单验证,除非您手动更改表,否则 DB 将使用 varchar(30) 而不是 EmailFieldvarchar(75)
  2. 您需要将电子邮件数据存储在用户名和电子邮件字段中,以使User.email_user() 正常工作。 User.email 使用时,我认为还有一些其他的地方。
  3. 代码可读性失败。当然,其他 djangonauts 知道这个陷阱,但是将名为“用户名”的字段(尤其是仍然存在电子邮件字段时)视为电子邮件显然会使您的代码更难理解。

另一种方法可能是使用email 字段进行身份验证,方法是将其传递给您的身份验证后端,但仍然存在问题:

authenticate(self, email=None, password=None)
  1. User.email 没有 unique=True 属性,这意味着您的数据库将没有索引,从而使您通过电子邮件查找的速度非常慢。
  2. 您必须处理具有unique=Trueusername 字段,将其从表中完全删除或更改为允许NULL 并删除索引。

恢复,这两种方式都是邪恶的,需要在syncdb之后执行特定于DB的代码,如果你需要独立于DB的应用程序,这是不可接受的。

【问题讨论】:

  • 很酷的问题,我也想知道如何在 Django 中使用电子邮件作为用户名 ;-)

标签: django email authentication


【解决方案1】:

David Cramer 想出了一个我喜欢的解决方案。我目前在生产站点上使用它,用户必须能够使用他们的电子邮件或用户名登录。你可以在这里找到它:

Logging In With Email Addresses in Django

如果表单上提供的登录名是电子邮件(包含“@”符号),它将尝试使用该登录名进行身份验证,如果不是电子邮件,则会使用用户名。 (当然,您只需要确保您的注册表单中包含此工作的电子邮件。)

【讨论】:

    【解决方案2】:

    我已经打包了django-email-as-username,如果你想删除用户名并且只使用电子邮件,它应该可以满足你的所有需求。

    简要概述是:

    1. 为创建用户提供电子邮件身份验证后端和帮助函数。
    2. 修补 Django 管理员以处理基于电子邮件的用户身份验证。
    3. 覆盖 createsuperuser 命令以仅使用电子邮件创建用户。
    4. 将电子邮件身份验证视为不区分大小写。

    在后台,用户名是电子邮件的散列版本,这最终意味着我们不受 Django 用户名 30 个字符的限制(只是常规电子邮件的 75 个字符限制。)

    编辑:从 Django 1.5 开始,您应该考虑使用自定义用户模型而不是“django-email-as-username”包。

    【讨论】:

      【解决方案3】:

      好吧,我不必在 Django 中使用电子邮件作为用户名,但我想您可以创建一个 UserProfile 模型并将字段聚合到它,就像另一个电子邮件字段一样,并使其独一无二。因此,您可以使用 user.get_profile().email 进行身份验证。

      我想其他方法是继承 User 并重新定义字段,但我认为 Django 开发人员仍然不推荐这样做。

      最后,您可以定义自己的自定义 User 模型并返回 django.contrib.auth.models.User 以获取一些逻辑。

      在 Django 中更改用户表的代码:

       from django.db import connection
       cursor = connection.cursor()
       cursor.execute("ALTER TABLE auth_user MODIFY COLUMN username varchar(75) NOT NULL")
      

      【讨论】:

      • 多表继承或修改 auth 应用程序的本地副本的坏处是无法定义其他贡献应用程序(如 admin、messages 或 cmets)应该使用什么模型。
      • 我明白了。如果您不想遵循选项 1,我想向 UserProfile 添加一个新字段是最好的方法。不确定,目前是否有任何其他方法。
      • 如果您想更加独立于 DB,您可以做的另一件事是添加此代码(已编辑答案),在您的 settings.py 中使用一个变量来指示它是否应该执行已修改。
      猜你喜欢
      • 2015-04-27
      • 2011-09-15
      • 2012-02-18
      • 2013-07-23
      • 1970-01-01
      • 2010-10-21
      • 2012-02-06
      • 2019-05-24
      相关资源
      最近更新 更多