【问题标题】:Using email as username with django在 django 中使用电子邮件作为用户名
【发布时间】:2012-02-18 04:04:27
【问题描述】:

尝试在 django 中创建用户时遇到以下错误:

>>> email = 'verylongemail@verylongemail.com'
>>> user_object = User.objects.create_user(username=email, email=email, password='password')
Data truncated for column 'username' at row 1

似乎 Django 对用户名中允许的字符数有限制。我该如何解决这个问题?

【问题讨论】:

  • 我刚刚进入并手动修改了 auth_user 表来解决这个问题。
  • 迄今为止最好的处理方式。谢谢。

标签: django


【解决方案1】:

我不得不手动修改 auth_user 表以使字段更长,然后通过删除 @ 符号和句点将电子邮件转换为用户名(也许还有其他字符,这真的不是一个很好的解决方案)。然后,您必须编写一个自定义身份验证后端,根据用户的电子邮件而不是用户名来验证用户身份,因为您只需要存储用户名来安抚 django。

换句话说,不再使用用户名字段进行身份验证,使用电子邮件字段并将用户名存储为电子邮件的版本以使 Django 满意。

他们对此主题的官方回应是,许多网站更喜欢使用用户名进行身份验证。这真的取决于你是在为用户创建一个社交网站还是一个私人网站。

【讨论】:

  • +1 很遗憾,这不是 django 内置的并且具有像 USER_AUTH_FIELD='EMAIL' 这样的设置,但实现自己并没有太大问题。有关示例后端,请参阅 here
  • 我也这样做了,但是因为
  • 所以 >= 1.2 允许在用户名中使用“@”?太好了,因为我也不喜欢这样做。谢谢!
【解决方案2】:

如果您为 Django 用户覆盖表单,您实际上可以非常优雅地完成此操作。

class CustomUserCreationForm(UserCreationForm):
"""
    The form that handles our custom user creation
    Currently this is only used by the admin, but it 

允许用户稍后自行注册是有意义的 """ email = forms.EmailField(required=True) first_name = forms.CharField(required=True) last_name = forms.CharField(required=True)

class Meta:
    model = User
    fields = ('first_name','last_name','email')

然后你可以在你的 backends.py 中放

class EmailAsUsernameBackend(ModelBackend):
"""
Try to log the user in treating given username as email.
We do not want superusers here as well
"""

def authenticate(self, username, password):
    try:
        user = User.objects.get(email=username)
        if user.check_password(password):
            if user.is_superuser():
                pass
            else: return user

    except User.DoesNotExist: return None

然后在你的 admin.py 中你可以覆盖

class UserCreationForm(CustomUserCreationForm):
"""
    This overrides django's requirements on creating a user

    We only need email, first_name, last_name
    We're going to email the password
"""
def __init__(self, *args, **kwargs):
    super(UserCreationForm, self).__init__(*args, **kwargs)
    # let's require these fields
    self.fields['email'].required       = True
    self.fields['first_name'].required  = True
    self.fields['last_name'].required   = True
    # let's not require these since we're going to send a reset email to start their account
    self.fields['username'].required    = False
    self.fields['password1'].required   = False
    self.fields['password2'].required   = False

我的还有一些其他修改,但这应该会让你走上正轨。

【讨论】:

    【解决方案3】:

    You have to modify the username length field 以便 syncdb 将创建适当长度的 varchar,您还必须修改 AuthenticationForm 以允许更大的值,否则您的用户将无法登录。

    from django.contrib.auth.forms import AuthenticationForm
    
    AuthenticationForm.base_fields['username'].max_length = 150
    AuthenticationForm.base_fields['username'].widget.attrs['maxlength'] = 150
    AuthenticationForm.base_fields['username'].validators[0].limit_value = 150
    

    【讨论】:

      猜你喜欢
      • 2015-04-27
      • 2013-07-23
      • 2011-04-02
      • 2011-09-15
      • 1970-01-01
      • 2019-05-24
      • 2012-02-06
      • 2010-10-21
      相关资源
      最近更新 更多