Форум сайта python.su
Здравствуйте!
Django 1.5, использую такую форму для авторизации (используется переопределенная модель MyUser):
model:
class LoginForm(forms.Form): username = forms.CharField(max_length=100) password = forms.CharField(widget=forms.PasswordInput(render_value=False),max_length=100)
def login_view(request): if request.method == 'POST': username = request.POST['email'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None and user.is_active: login(request, user) return HttpResponseRedirect("/n1.html")# Redirect to a success page. return HttpResponseRedirect("/invalid/")# Return a 'disabled account' error message form=LoginForm() return render(request, 'enter.html', {'login_form': LoginForm})
(r'^login/$', login_view),
Офлайн
Офлайн
Я такое аяксом делаю, только Class-Based View'хи использую, ну принцип похож конечно.
Смысл вообще в том что данные с формы отсылаются Ajax Postом.
Если логин ОК- пользователь логинится и страничка перегружается(можно и редиректить куда надо), если нет- в placeholder полей прилетают ошибки, довольно удобно получается в инпуты ошибки писать в обратку.
P.S. в 1.5 надо не забывать get_user_model() использовать для доступа к модели пользователя
Форма такая же в целом, ну я еще проверку добавляю.
class LoginForm(forms.Form): username = forms.CharField(label=_('Username'), max_length=30) password = forms.CharField(label=_('Password'), max_length=30) class Meta: widgets = dict(password=forms.PasswordInput) def clean_username(self): username = self.cleaned_data["username"] if not username: raise forms.ValidationError(_("THIS FIELD IS REQUIRED")) try: user = get_user_model().objects.get(username=username) if not user.is_active: raise UserIsDisabled return username except get_user_model().DoesNotExist: raise forms.ValidationError(_("THE USER IS NOT EXIST")) except UserIsDisabled: raise forms.ValidationError(_("THE USER IS DISABLED")) def clean_password(self): username = self.cleaned_data["username"] password = self.cleaned_data["password"] user = authenticate(username=username, password=password) if not user: raise forms.ValidationError(_("THIS PASSWORD IS INCORRECT")) return password class LoginView(FormView): form_class = LoginForm def form_valid(self, form): username = form.cleaned_data.get('username') password = form.cleaned_data.get('password') user = authenticate(username=username, password=password) login(self.request, user) payload = {'success': True} return HttpResponse(json.dumps(payload, cls=LazyEncoder), content_type='application/json') def form_invalid(self, form, *args, **kwargs): # Ошибки формы кидаем в словарь, чтобы отправить клиенту, функция ниже payload = {'success': False, 'errors': as_json(form.errors)} return HttpResponse(json.dumps(payload, cls=LazyEncoder), content_type='application/json') def as_json(errors): return dict((k, map(unicode, v)) for k, v in errors.items())
// Просто функция которая пишет в Placeholder ошибки поля , а общие ошибки формы в добавленный перед формой DIV function AjaxFormError(errors, $form) { for (var k in errors) { // Не забываем стереть введенные значения в форме, перед тем как записать ошибки $('[name="'+k+'"]').val('').prop('placeholder', errors[k]); if (k == '__all__') // Если ошибки не поля, а всей формы- допишем слой выше { $form.prepend('<div class="error">' + errors[k] + '</div>'); } } } // Ииии..все вместе :) $(document).ready(function(){ $('#login_link').click( function() { $.post("{% url 'login' %}", $("#login_form").serialize(),function(data) { $("#login_form").find('.error').html(''); if (data.success == true) { window.location.reload(); } else { AjaxFormError(data['errors'], $('#login_form')); } }); return false; }); })
Отредактировано nnmware (Фев. 26, 2013 00:47:04)
Офлайн
nnmwareСпасибо. Но пока решил сделать попроще, чтоб самому было понятно:
def login_view(request): if request.method == 'POST': username = request.POST['email'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None and user.is_active: login(request, user) return HttpResponseRedirect("/n1.html") return render_to_response('enter.html', {'error': True}) form=LoginForm() return render(request, 'enter.html', {'login_form': LoginForm})
enter.html {% if error %} 'Неверное имя или пароль' {% endif %} <form class="form-signin" action="" method="post"> {% csrf_token %} <h2 class="form-signin-heading">Пожалуйста, авторизуйтесь</h2> <input class="input-block-level" type="text" name="email" value="" id="email" placeholder="Email адрес"> <input class="input-block-level" type="password" name="password" value="" id="username" placeholder="Пароль"> <button class="btn btn-large btn-primary" type="submit">Вход</button> <input type="hidden" name="next" value="{{next|escape}}" > </form>
Отредактировано dnstuff (Фев. 26, 2013 14:22:34)
Офлайн
Заработало бы и вот так - render_to_response('enter.html', {'error': True, context_instance=RequestContext(request) })
По умолчанию в render_to_response используются только данные из предоставленного словаря, в Вашем случае- только error. В шаблоне не виден request, а {% csrf_token %} из него дергает значение ключа, чтобы рендерить скрытое поле.
Соответственно чтобы использовать процессоры контекста- надо передать экземляр RequestContext.
http://djbook.ru/rel1.4/topics/http/shortcuts.html#id2
P.S. Судя по коду, если бы у Вас было debug=True, то джанга бы сама это сказала.
Офлайн