2015-12-03 1 views
0

Это пользовательское окно входа в систему, которое я написал, потому что мне нужно войти в систему с его электронной почтой, а не с его именем пользователя.Django FormView действителен, но мне нужно добавить_error и вернуть тот же вид

class LoginUser(FormView): 
    """ 
    Login with email 
    """ 
    template_name = "profiles/login.html" 
    form_class = LoginForm 
    success_url = reverse_lazy("client:profile") 

    def form_valid(self, form): 
     user_email = form.cleaned_data['user_email'] 
     password = form.cleaned_data['password'] 

     user_object = User.objects.get(email=user_email) 
     user = authenticate(username=user_object.username, password=password) 

     # !!! Problem here when user is None 

     login(self.request, user) 

     return super(LoginUser, self).form_valid(form) 

Когда user является None, то есть метод authenticate вернулся None причиной пароль был неправильным. Мне нужно добавить ошибку и вернуть тот же вид, но с ошибкой: «неправильное имя пользователя или пароль». Как я могу достичь этого, используя классные представления? (Обычно я использую функции, основанные на представлениях, но на этот раз я решил иначе).

Редактировать

Sayse ответ на этот вопрос работает частично, он правильно перемещает логику проверки методу clean. Но теперь я получаю ошибку

Django-AttributeError 'User' object has no attribute 'backend'

Эта ошибка происходит, когда есть вызов login на объекте пользователя, не вызывая authenticate этого объекта пользователя первый. Должен ли я поставить вызов login внутри метода clean?

+3

Не было бы лучше назвать 'authenticate' в файле' Метод «чистый» LoginForm'? Я думаю, что 'form_valid' вызывается только в том случае, если форма действительна. –

+1

@ShangWang - Не могли бы вы ответить на свой комментарий? его правильно, и я действительно не хочу брать на это кредит – Sayse

+2

@Sayse: Все в порядке. Пока ваш ответ помог (в конце концов, я не потратил столько времени, как вы, чтобы написать ответ :)). –

ответ

2

Как отмечает Шан Ван в комментариях, вы должны делать такие вещи в чистом виде формы, но для этого вам нужно пройти через объект запроса.

FormView

def get_form_kwargs(self): 
    kwargs = super(LoginUser, self).get_form_kwargs() 
    kwargs['request'] = self.request 
    return kwargs 

LoginForm

def __init__(self, *args, **kwargs): 
    self.request = kwargs.pop('request') 
    super(LoginForm , self).__init__(*args, **kwargs) 

Теперь вы будете иметь возможность вызывать аутентификации в чистом методе формы.

authenticate(username=self.request.user.username, password=password) 

Все вышесказанное не имеет значения и избыточна, вам нужно только переместить логику в чистом методе формы в

def clean(self): 
    cleaned_data = super(LoginForm , self).clean() 
    user_email = cleaned_data['user_email'] 
    subject = cleaned_data.get("subject") 

    user_object = User.objects.get(email=user_email) 
    user = authenticate(username=user_object.username, password=password) 
    if user is None: 
     self.add_error('user_email', 'Invalid Password') 
+0

Примечание: вы могли бы просто пройти через пользователя. Вы также не укажете, что 'correo' равно – Sayse

+0

Спасибо за ответ, я проверю его, а затем приму его. 'correcto' является ошибкой, уже исправил ее. Я перевел код на английский, чтобы он более удобен для чтения для людей в SO. – alejoss

+0

@alejoss - О, ваше обновление делает это еще проще, вам просто нужно использовать форму clean method – Sayse

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

  • Нет связанных вопросов^_^