在Django中将电子邮件地址作为用户名

85 投票
12 回答
47581 浏览
提问于 2025-04-15 11:12

有没有什么好的方法可以在Django中做到这一点,而不需要自己去做一个认证系统?我想让用户名用用户的邮箱地址,而不是让他们自己创建一个用户名。

请给点建议

12 个回答

22

这里有一种方法可以让用户名和邮箱都能被接受:

from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.forms import ValidationError

class EmailAuthenticationForm(AuthenticationForm):
    def clean_username(self):
        username = self.data['username']
        if '@' in username:
            try:
                username = User.objects.get(email=username).username
            except ObjectDoesNotExist:
                raise ValidationError(
                    self.error_messages['invalid_login'],
                    code='invalid_login',
                    params={'username':self.username_field.verbose_name},
                )
        return username

我不知道是否有设置可以更改默认的认证表单,但你也可以在urls.py文件中覆盖这个网址。

url(r'^accounts/login/$', 'django.contrib.auth.views.login', { 'authentication_form': EmailAuthenticationForm }, name='login'),

抛出ValidationError可以防止在提交无效邮箱时出现500错误。使用父类的“invalid_login”定义可以让错误信息保持模糊(而不是具体的“没有找到这个邮箱的用户”),这样可以避免泄露某个邮箱是否已经注册了你的服务。如果你的系统架构不够安全,可能更友好的是提供一个更详细的错误信息。

29

我们这样做。这不是一个“完整”的解决方案,但它能满足你大部分的需求。

from django import forms
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        exclude = ('email',)
    username = forms.EmailField(max_length=64,
                                help_text="The person's email address.")
    def clean_email(self):
        email = self.cleaned_data['username']
        return email

class UserAdmin(UserAdmin):
    form = UserForm
    list_display = ('email', 'first_name', 'last_name', 'is_staff')
    list_filter = ('is_staff',)
    search_fields = ('email',)

admin.site.unregister(User)
admin.site.register(User, UserAdmin)
35

如果你也想这样做,我建议你看看 django-email-as-username 这个项目,它提供了一个很全面的解决方案,包括对管理后台和 createsuperuser 命令的修补,还有其他一些功能。

补充说明: 从 Django 1.5 版本开始,你应该考虑使用 自定义用户模型,而不是 django-email-as-username

撰写回答