Form.errors не отображается при неправильном отправлении формы
У меня возникают трудности с отображением на странице определенных пользователем ошибок, когда пользователь отправляет недопустимую форму. Я установил novalidate
на элемент формы с целью отключения сообщений о проверке формы по умолчанию в браузере. В то же время сообщения об ошибках, определенные в QuestionForm
, не отображаются на странице.
Мне неясно, почему сообщения об ошибках формы не отображаются? Является ли установка novalidate
причиной этого?
class Page(TemplateView):
def get_context_data(self, **kwargs):
context = super().get_context_data()
context['search_form'] = SearchForm()
return context
class AskQuestionPage(Page):
template_name = "posts/ask.html"
extra_context = {
'title': "Ask a public question"
}
def attach_question_tags(self, tags):
question_tags = []
for name in tags:
try:
tag = Tag.objects.get(name=name)
except Tag.DoesNotExist:
tag = Tag.objects.create(name=name)
finally:
question_tags.append(tag)
return question_tags
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = QuestionForm
return context
def post(self, request):
context = self.get_context_data()
form = context['form'](request.POST)
if form.is_valid():
tags = self.attach_question_tags(
[tag.lower() for tag in form.cleaned_data.pop("tags")]
)
try:
question = form.save(commit=False)
question.profile = request.user.profile
question.save()
except IntegrityError:
form.add_error(None, "This post is already posted")
context['form'] = form
else:
question.tags.add(*tags)
form.save_m2m()
return SeeOtherHTTPRedirect(
reverse("posts:question", kwargs={
"question_id": question.id
})
)
return self.render_to_response(context)
<div class="question_posting_form">
<h2>{{ title }}</h2>
{% if form.non_field_errors %}
<ul class="non_field_errors">
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{{ form.errors }}
{% if form.errors %}
<ul class="non_field_errors">
{% for error in form.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<form id="postform" method="post" action="{{ request.path }}" novalidate>
{% csrf_token %}
{% for field in form %}
{% if field.html_name == "body" %}
<div class="content_posting">
{% include "./markdown_help.html" %}
<fieldset class="form_fieldset_widget">
<p>{{ field.label }}<p>
<p>{{ field.help_text }}</p>
{{ field }}
</fieldset>
<div class="post_draft" id="post_preview_question"></div>
</div>
{% elif field.html_name == "tags" %}
<fieldset id="tag_fieldset" class="form_fieldset_widget">
<p>{{ field.label }}</p>
<p>{{ field.help_text }}</p>
<div class="tag_boxes">
{% for field in field.subwidgets %}
{{ field }}
{% endfor %}
</div>
</fieldset>
{% else %}
<fieldset class="form_fieldset_widget">
<p>{{ field.label }}<p>
<p>{{ field.help_text }}</p>
{{ field }}
</fieldset>
{% endif %}
{% endfor %}
{% if request.resolver_match.url_name == "edit" %}
<button id="submit_question" type="submit">Edit Question</button>
{% else %}
<button id="submit_question" type="submit">Ask Question</button>
{% endif %}
</form>
</div>
class MultiTagWidget(MultiWidget):
def __init__(self, *args, **kwargs):
widgets = [TextInput(attrs=kwargs['attrs']) for i in range(4)]
for i, w in enumerate(widgets):
w.attrs.update({"placeholder": f"Tag {i}"})
super().__init__(widgets, *args, **kwargs)
def decompress(self, value):
if not value:
return ["", "", "", ""]
return value
class TagField(MultiValueField):
def __init__(self, *args, **kwargs):
fields = []
for i in range(4):
field = CharField(**{
"min_length": 1, "max_length": 25, "validators":[
RegexValidator("[<>`':;,.\"]", inverse_match=True)
]
})
if i == 0:
field.error_messages = {
'incomplete': "Provide at least 1 tag for your question"
}
field.required = True
else:
field.required = False
fields.append(field)
super().__init__(fields, *args, **kwargs)
def compress(self, data_list):
field_values = list(set([data.strip() for data in data_list if data]))
return field_values
class PostingForm(ModelForm):
body = CharField(
widget=Textarea(
attrs={
"class": "question_input_shade fill_block_width adjust_box"
}
), min_length=50
)
class Meta:
model = None
fields = ['body']
class QuestionForm(PostingForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['body'].help_text = "Clarify your question with as much detail as possible"
self.fields['body'].error_messages={
'required': "Elaborate on your question",
'min_length': "Add more info to your question"
}
title = CharField(
min_length=20, max_length=80,
widget=TextInput({"class": "question_input_shade fill_block_width"}),
error_messages={"max_length": "The title of your question is too long"},
help_text="Concisely describe the issue"
)
tags = TagField(
widget=MultiTagWidget(
attrs={
"min_length": 1, "max_length": 25,
"class": "question_input_shade inline_tag_input"
}
), require_all_fields=False,
help_text="Add up to 4 tags for your question"
)