Django Forms: 如果无效,则显示带有错误消息的表单

在 Django 表单中,它可以检查表单是否有效:

if form.is_valid():
return HttpResponseRedirect('/thanks/')

但是如果它是无效的,我会错过该怎么做?如何返回带有错误消息的表单?我在任何示例中都没有看到“ else”。

207913 次浏览

如果在表单无效时呈现相同的视图,那么在模板中可以使用 使用 form.errors访问表单错误

{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>\{\{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>\{\{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}

举个例子:

def myView(request):
form = myForm(request.POST or None, request.FILES or None)
if request.method == 'POST':
if form.is_valid():
return HttpResponseRedirect('/thanks/')
return render(request, 'my_template.html', {'form': form})

视野,视野

from django.contrib import messages


def view_name(request):
if request.method == 'POST':
form = form_class(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks'/)
else:
messages.error(request, "Error")
return render(request, 'page.html', {'form':form_class()})

如果您想显示表单中的错误而不是无效的错误,只需像我下面所做的那样放置\{\{ form.as _ p }}

Page.html

<html>
<head>
<script>
{% if messages %}
{% for message in messages %}
alert('\{\{message}}')
{% endfor %}
{% endif %}
</script>
</head>
<body>
\{\{form.as_p}}
</body>
</html>
def some_view(request):
if request.method == 'POST':
form = SomeForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks'/)
else:
form = SomeForm()
return render(request, 'some_form.html', {'form': form})

您可以简单地放置一个标志变量,在本例中为 成功了

def preorder_view(request, pk, template_name='preorders/preorder_form.html'):
is_successed=0
formset = PreorderHasProductsForm(request.POST)
client= get_object_or_404(Client, pk=pk)
if request.method=='POST':
#populate the form with data from the request
# formset = PreorderHasProductsForm(request.POST)
if formset.is_valid():
is_successed=1
preorder_date=formset.cleaned_data['preorder_date']
product=formset.cleaned_data['preorder_has_products']
return render(request, template_name, {'preorder_date':preorder_date,'product':product,'is_successed':is_successed,'formset':formset})






return render(request, template_name, {'object':client,'formset':formset})

之后,在您的模板中,您可以只是将代码放在下面

{%if is_successed == 1 %}
<h1>\{\{preorder_date}}</h1>
<h2> \{\{product}}</h2>
{%endif %}

更新: 添加了格式集错误的更详细说明。


Form.error 将所有字段和 non _ field _ error 组合在一起,因此可以将 html 简化为:

模板

    {% load form_tags %}


{% if form.errors %}
<div class="alert alert-danger alert-dismissible col-12 mx-1" role="alert">
<div id="form_errors">
{% for key, value in form.errors.items %}
<span class="fieldWrapper">
\{\{ key }}:\{\{ value }}
</span>
{% endfor %}
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endif %}




If you want to generalise it you can create a list_errors.html which you include in every form template. It handles form and formset errors:


{% if form.errors %}
<div class="alert alert-danger alert-dismissible col-12 mx-1" role="alert">
<div id="form_errors">


{% for key, value in form.errors.items %}
<span class="fieldWrapper">
\{\{ key }}:\{\{ value }}
</span>
{% endfor %}
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% elif formset.total_error_count %}
<div class="alert alert-danger alert-dismissible col-12 mx-1" role="alert">
<div id="form_errors">
{% if formset.non_form_errors %}
\{\{ formset.non_form_errors }}
{% endif %}
{% for form in formset.forms %}
{% if form.errors %}
Form number \{\{ forloop.counter }}:
<ul class="errorlist">
{% for key, error in form.errors.items %}
<li>\{\{form.fields|get_label:key}}
<ul class="errorlist">
<li>\{\{error}}</li>
</ul>
</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}


</div>
</div>


{% endif %}

Form _ tag. py

from django import template


register = template.Library()




def get_label(a_dict, key):
return getattr(a_dict.get(key), 'label', 'No label')




register.filter("get_label", get_label)


一个警告: 与表单 Formset.error 不包括 non _ field _ error 相反。

您可以这样做,因为当您初始化表单时,其中包含表单数据和无效数据:

def some_func(request):
form = MyForm(request.POST)
if form.is_valid():
//other stuff
return render(request,template_name,{'form':form})

如果模板中有任何错误,但表单数据仍然保持为:

Error _ demo _ here

@ AamirAdnan 的答案缺少 field.label; 另一种方式显示错误在几行。

{% if form.errors %}
<!-- Error messaging -->
<div id="errors">
<div class="inner">
<p>There were some errors in the information you entered. Please correct the following:</p>
<ul>
{% for field in form %}
{% if field.errors %}<li>\{\{ field.label }}: \{\{ field.errors|striptags }}</li>{% endif %}
{% endfor %}
</ul>
</div>
</div>
<!-- /Error messaging -->
{% endif %}

这个回答 是正确的,但有一个问题: 字段没有定义。 如果有多个字段,则无法识别哪个字段有错误。

通过此更改,您可以显示字段名:

{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>\{\{ field.label }}</strong><span>\{\{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>\{\{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}