Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 5, 2014 00:49:48

demiurg
Зарегистрирован: 2014-11-05
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Форма не отображает ошибки

Доброго времени суток! Помогите, пожалуйста новичку.
Создаю простую форму для входа в систему:

class LoginForm(forms.ModelForm):
	password = forms.CharField(widget = forms.PasswordInput(), label = 'Your Password')
	class Meta:
		model = User
		fields = ('username', 'password')
Для отображения использую CBV:
class WelcomeView(View):
	http_method_names = ['get','post']
	def get(self, request):
		template_name = 'Welcome.html'
		form = LoginForm()
		return render(request,template_name,{'form':form})
	def post(self, request):
		logout(request)
		form = LoginForm(request.POST)
		if form.is_valid():
			username = form.cleaned_data['username']
			password = form.cleaned_data['password']
			user = authenticate(username = username, password = password)
			if user is not None:
				if user.is_active:
					login(request,user)
					return redirect('schedule')
				else:
					print('User is inactive')
			else:
				print('Invalid login')
				print(form.errors)
		else:
			print('Not valid!', form.errors)
			form = LoginForm()
		return reverse('welcome')
А это html:
<p>Please, login to proceed...</p>
	{% if form.errors %}
	<p> Your username and password didn't math</p>
	{% endif %}
	<form name = "LoginForm"action = "{{action}}" method="post">
		{% csrf_token %}
  		{% if form.non_field_errors %}
		<div class="form_errors">
  		{% for err in form.non_field_errors %}
  		<div class="form_error_message">{{ err }}</div>
  		{% endfor %}
		</div>	
		{% endif %}
		{% for hidden in form.hidden_fields %}
   		{{ hidden }}
		{% endfor %}
		{% for field in form.visible_fields %}
 		<div {% if field.errors %}class="field_error"{% endif %}>
    	{{ field.label_tag }}
    	{{ field }}
    	{% for err in field.errors %}
    	<span class="error_message">{{ err }}</span>
    	{% endfor %}
  		</div>
		{% endfor %}
  		{% for i in form.errors %}
  			{{ i }}
  		{% endfor %}
  		<input type="submit" value = "login">
	</form>
Форма работает: пользователь авторизируется и переходит в нужное место. Но форма не отображает ошибки. Т.е. если отправить пустые поля или одно пустое, то это никак не сообщается. Так же хотелось бы чтобы форма сообщала если пользователь отключен или введено слишком много символов (30 по умолчанию).
После прочтения документации и топиков форума ни один из способов не помог. Думал что как-то не так работает, и смог только отлавливать ошибки. Понимаю что их надо передавать обратно, но опыта не хватает это сделать.
Помогите, пожалуйста.
Буду благодарен за подробный ответ, а так же если “ткнете носом” где про это читать, т.к. документацию читал 2 раза

Отредактировано demiurg (Ноя. 5, 2014 00:52:32)

Офлайн

#2 Ноя. 5, 2014 01:02:55

DayFan
От:
Зарегистрирован: 2011-01-09
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Форма не отображает ошибки

Когда форма не валидна (т.е. c ошибками) вы должны ее передать обратно в template.



Офлайн

#3 Ноя. 5, 2014 01:13:38

demiurg
Зарегистрирован: 2014-11-05
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Форма не отображает ошибки

Когда форма не валидна (т.е. c ошибками) вы должны ее передать обратно в template.

Я это понимаю, но опыта не хватает это сделать. Как это реализовать?

Офлайн

#4 Ноя. 5, 2014 01:32:41

DayFan
От:
Зарегистрирован: 2011-01-09
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Форма не отображает ошибки

demiurg
return render(request,template_name,{'form':form})
Примерно так же как вы и до этого отправляли форму
return render(request,template_name,{'form':form})
После того как вы проверили форму form.is_valid() заполняется словарь form.error где и хранятся ошибки. И эту же форму, но уже с ошибками вы передаете обратно в template.



Офлайн

#5 Ноя. 5, 2014 11:46:37

GreyZmeem
От: Киев
Зарегистрирован: 2013-12-03
Сообщения: 147
Репутация: +  34  -
Профиль   Отправить e-mail  

Форма не отображает ошибки

form = LoginForm(request.POST)
if form.is_valid():
    ...
    return reverse('welcome')
print('Not valid!', form.errors)
# form = LoginForm()  # Вот этого делать не надо, т.к. вы форму которая содержит ошибки затираете пустой формой
return render(request,template_name,{'form':form})

Офлайн

#6 Ноя. 5, 2014 16:31:32

demiurg
Зарегистрирован: 2014-11-05
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Форма не отображает ошибки

Воспользовался вашим советом. Теперь ошибки выводятся, но не происходит авторизация. При введении правильных данных выдается сообщение об ошибке : “Пользователь с таким именем уже существует”.
Так же хотелось бы реализовать функционал сообщения о том что пользователь неактивный или введен неправильный пароль. Для этого необходимо переопределить методы в классе формы (если да, то как правильно?) или достаточно будет вызвать ошибку валидации в теле функции типа:

raise forms.ValidationError("This user is inactive!")

Отредактировано demiurg (Ноя. 5, 2014 16:33:01)

Офлайн

#7 Ноя. 7, 2014 16:33:47

demiurg
Зарегистрирован: 2014-11-05
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Форма не отображает ошибки

Для всех, кому может быть интересно или пригодится!
Вопрос решился следующим образом.
Код модели:

class LoginForm(forms.Form):
	username = forms.CharField(label = 'Your Name')
	password = forms.CharField(widget = forms.PasswordInput(), label = 'Your Password')
	def clean_username(self):
		username = self.cleaned_data['username']
		try:
			user = User.objects.get(username = username)
			if not user.is_active:
				raise forms.ValidationError("User is inactive!")
			else:
				return username
		except User.DoesNotExist:
			raise forms.ValidationError("User not Exist!")
А так выглядит views.py:
class WelcomeView(View):
	http_method_names = ['get','post']
	def get(self, request):
		template_name = 'Welcome.html'
		form = LoginForm()
		print(form.errors)
		return render(request,template_name,{'form':form})
	
	def post(self, request):
		logout(request)
		template_name = 'Welcome.html'
		form = LoginForm(request.POST)
		if form.is_valid():
			username = form.cleaned_data['username']
			password = form.cleaned_data['password']
			user = authenticate(username = username, password = password)
			if user is not None:
				if user.is_active:
					login(request,user)
					return redirect('schedule')
				else:
					print('User is inactive')
					
			else:
				print('Invalid login')
				print(form.errors)
		else:
			print('Not valid!', form.errors)
		return render(request, template_name,{'form':form})
Как видно из кода, я отказался от наследования класса ModelForm, а наследую класс Form. После этого форма заработала и стала пускать в систему, а не проверять наличие пользователя. Так же для добавления проверки “неактивного пользователя” или его существования был переопределен метод clean_username. В файле видов, по совету GreyZmeem, были внесены изменения в метод post в случае неверности формы:
return render(request, template_name,{'form':form})
(последняя строка).
Как итог, форма работает, и сообщает о необходимых мне ошибках при проверки пользователя.
Всем, большое спасибо за помощь!

Офлайн

#8 Ноя. 17, 2014 18:47:24

den4ik
Зарегистрирован: 2014-07-20
Сообщения: 59
Репутация: +  4  -
Профиль   Отправить e-mail  

Форма не отображает ошибки

А зачем так издеваться?
Если свой шаблон хочется использовать, то можно проще поступить.

# views.py
from django.contrib.auth import views as auth_views
   
def login_view(request):
    if request.user.is_authenticated():
        return HttpResponseRedirect('/')
    return auth_views.login(request, template_name='profiles/login.html')
    
# urls.py
...
url(r'^login/$', login_view, name='login'),
...
Все стандартные ошибки показываются, если шаблон правильно сделать.

Отредактировано den4ik (Ноя. 17, 2014 18:50:12)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version