使用电子邮件作为Django的用户名

3
我遇到了在 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 对用户名中允许的字符数有限制。我该如何解决这个问题?


1
我刚刚手动修改了auth_user表来解决这个问题。 - Brandon Taylor
迄今为止处理它的最佳方式。谢谢。 - David542
3个回答

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

我的版本有一些其他的修改,但这应该能让你朝着正确的方向前进。

2
我不得不手动修改auth_user表格,使字段更长,并通过删除@符号和句点(也许还有其他字符,这真的不是一个好的解决方案)将电子邮件转换为用户名。然后,您需要编写自定义auth后端以根据用户的电子邮件而不是用户名进行身份验证,因为您只需要存储用户名以取悦Django。
换句话说,不要再使用用户名字段进行身份验证,改用电子邮件字段,并将用户名存储为电子邮件的一个版本以满足Django的要求。
他们在此问题上的官方回应是,许多网站更喜欢使用用户名进行身份验证。这实际上取决于您是要创建社交网站还是仅为用户创建私人网站。

+1 这不是内置在 Django 中并且没有像 USER_AUTH_FIELD='EMAIL' 这样的设置,但自己实现也不是太麻烦。请参见此处以获取示例后端。 - T I
我也做过这个,但因为<1.2版本不允许在用户名字段中使用“@”符号,所以现在我宁愿修改字段长度而不改变其他任何内容。 - Yuji 'Tomita' Tomita
那么 >= 1.2 版本允许在用户名中使用 '@' 符号了吗?太好了,因为我也不喜欢这样做。谢谢! - Max

1

你需要修改用户名长度字段,以便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

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