2010-05-30 6 views
4

Django новичок здесь.Пользовательский логин в Django

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

По умолчанию каждый класс Field предполагает, что это значение необходимо, поэтому, если вы передаете пустое значение - либо None, либо пустую строку ("") - затем очистите() возбудит исключение 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

['django.contrib.auth.forms.AuthenticationForm'] (http://github.com/jacobian/django/blob/master/django/contrib/auth/forms.py#L54) доставка с помощью django довольно прост и прочен. Если у вас нет насущной необходимости, просто используйте это. – miku

+0

Я аутентифицируюсь по электронной почте и паролю, а не по имени пользователя и паролю. – mgs

+1

Скорее посмотрите на что-то вроде этого: [Вход в систему с адресами электронной почты в Django] (http://www.davidcramer.net/code/224/logging-in-with-email-addresses-in-django.html) – miku

ответ

4

Вы можете использовать Джанго встроенный способ переопределить как аутентификация происходит путем установки 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

Сценарий Дэвида Крамера более эффективен, чем мой, так как он настраивает kwargs поиска с помощью команды «@» в имени пользователя. Я принял его метод. – Brandon

Смежные вопросы