Пользовательский вход в Django - PullRequest
5 голосов
/ 30 мая 2010

Джанго новичок здесь.

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

По умолчанию каждый класс Field предполагает, что значение является обязательным, поэтому если вы передадите пустое значение - None или пустую строку ("") - тогда clean () вызовет исключение ValidationError

Я пытался написать свои собственные валидаторы для полей (clean_email и clean_password), но это не работает (т.е. я получаю исключение KeyError). Что я делаю не так?

class LoginForm(forms.Form):
    email = forms.EmailField(label=_(u'Your email'))
    password = forms.CharField(widget=forms.PasswordInput, label=_(u'Password'))

    def clean_email(self):
        data = self.cleaned_data['email']
        if not data:
            raise forms.ValidationError(_("Please enter email"))
        return data

    def clean_password(self):
        data = self.cleaned_data['password']
        if not data:
            raise forms.ValidationError(_("Please enter your password"))
        return data

    def clean(self):
        try:
            username = User.objects.get(email__iexact=self.cleaned_data['email']).username
        except User.DoesNotExist:
            raise forms.ValidationError(_("No such email registered"))
        password = self.cleaned_data['password']

        self.user = auth.authenticate(username=username, password=password)
        if self.user is None or not self.user.is_active:
            raise forms.ValidationError(_("Email or password is incorrect"))
        return self.cleaned_data

Ответы [ 2 ]

4 голосов
/ 17 марта 2011

Вы можете использовать встроенный в Django способ переопределить аутентификацию, установив AUTHENTICATION_BACKENDS в ваших settings.py

Вот мой EmailAuthBackend:

#settings.py
AUTHENTICATION_BACKENDS = (
    'auth_backend.auth_email_backend.EmailBackend',
    'django.contrib.auth.backends.ModelBackend',
)

#auth_email_backend.py
from django.contrib.auth.backends import ModelBackend
from django.forms.fields import email_re
from django.contrib.auth.models import User

class EmailBackend(ModelBackend):
    """
    Authenticate against django.contrib.auth.models.User
    """

    def authenticate(self, **credentials):
        return 'username' in credentials and \ 
            self.authenticate_by_username_or_email(**credentials)

    def authenticate_by_username_or_email(self, username=None, password=None):
        try:
            user = User.objects.get(email=username)
        except User.DoesNotExist:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                user = None
        if user:
            return user if user.check_password(password) else None
        else:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

#forms.py
#replaces the normal username CharField with an EmailField
from django import forms
from django.contrib.auth.forms import AuthenticationForm

class LoginForm(AuthenticationForm):
    username = forms.EmailField(max_length=75, label='Email')
    next = forms.CharField(widget=forms.HiddenInput)

Надеюсь, это поможет!

0 голосов
/ 08 февраля 2019

С Django 2.0 добиться этого еще проще.

Создайте свою собственную модель пользователя

class User(AbstractBaseUser, PermissionsMixin):

и установите USERNAME_FIELD = 'email'

Для справки: Документация

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...