8

我在我的应用程序中使用内置登录。有一些自定义后端或包来处理这个问题。但其中许多不是我想要的。

我在注册时通过 django-registration 使电子邮件独一无二。现在我只想在登录页面而不是用户名中询问电子邮件。

但如果我使用一些自定义后端(如django 电子邮件)作为用户名,它在与 django-registration 一起使用时会崩溃。

我不想更改所有身份验证后端,我只想更改登录页面。

在站点的其余部分,我将使用用户名。pe 在我的自定义管理页面中,当我写:

welcome {{user}}

它必须呈现用户名。不是电子邮件。

我需要找到解决办法。我被困住了。

谢谢你。

4

2 回答 2

10

默认情况下django.contrib.auth.urls将从此模式创建一个登录页面

(r'^login/$', 'django.contrib.auth.views.login'),

您需要避免/覆盖此 url,然后创建一个新视图来处理新类型的登录。

例如

在 urls.py 中创建一个新的登录 url

(r'^emaillogin/$', 'email_login_view'),

在views.py中创建视图以支持使用电子邮件登录

# get default authenticate backend
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User

# create a function to resolve email to username
def get_user(email):
    try:
        return User.objects.get(email=email.lower())
    except User.DoesNotExist:
        return None

# create a view that authenticate user with email
def email_login_view(request):
    email = request.POST['email']
    password = request.POST['password']
    username = get_user(email)
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            # Redirect to a success page.
        else:
            # Return a 'disabled account' error message
    else:
        # Return an 'invalid login' error message.

参考:https ://docs.djangoproject.com/en/1.4/topics/auth/#django.contrib.auth.login

于 2012-11-18T14:23:46.480 回答
2

上述方法在 django 1.9 上不再适用。另一种方法可能是将视图中使用的身份验证表单覆盖为:

class EmailLoginForm(AuthenticationForm):
def clean(self):
    try:
        self.cleaned_data["username"] = get_user_model().objects.get(email=self.data["username"])
    except ObjectDoesNotExist:
        self.cleaned_data["username"] = "a_username_that_do_not_exists_anywhere_in_the_site"
    return super(EmailLoginForm, self).clean()

然后在定义登录url时,定义如下:

url(r'^login/$', django.contrib.auth.views.login, name="login", kwargs={"authentication_form": EmailLoginForm}),
url(r'^', include('django.contrib.auth.urls')),

上述方法最好的一点是,您在身份验证过程中并没有真正触及任何东西。这不是一个真正的“干净”解决方案,但它是一个快速的解决方法。当您在包含 auth.urls 之前定义登录路径时,它将被评估而不是基本登录表单

于 2016-03-30T12:31:26.390 回答