Django-как использовать встроенный вид входа с электронной почтой вместо имени пользователя?

Я использую встроенный логин в своем приложении. Существует несколько пользовательских бэкэндов или пакетов для обработки этого. но многие из них не то, что я ищу.

Я сделал электронную почту уникальной через django-Регистрация при регистрации. теперь все, что я хочу, это спросить электронную почту на странице входа вместо имени пользователя.

но если я использую некоторые пользовательские бэкэнды, такие как django email как имя пользователя он падает при использовании с django-регистрацией.

Я не хочу менять все аутентификация бэкэнд, я просто хочу изменить страницу входа в систему.

в остальной части сайта , я буду использовать имя пользователя. С. е в мой пользовательский админ страницы, когда я пишу:

welcome {{user}}

он должен отображать имя пользователя. не по электронной почте.

Мне нужно найти выход из этого. я застрял.

спасибо.

2 ответов


по умолчанию django.contrib.auth.urls создаст страницу входа в систему из этого шаблона

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

вам нужно избежать / переопределить этот url-адрес, а затем создать новое представление для обработки нового типа входа.

например

создайте новый url-адрес входа в систему urls.py

(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.

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


вышеуказанный подход больше не работает на django 1.9. Другим подходом может быть переопределение формы auth, используемой в представлении как:

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, он будет оценен вместо базовая форма входа