Python 使用标签而不是字段名呈现表单错误
我想使用模板中的{{form.errors}}将所有表单错误一起列出。这将生成表单字段列表和每个字段的错误嵌套列表。但是,将使用字段的文字名称。生成的html在特定字段中出现错误,可能如下所示Python 使用标签而不是字段名呈现表单错误,python,django,django-forms,Python,Django,Django Forms,我想使用模板中的{{form.errors}}将所有表单错误一起列出。这将生成表单字段列表和每个字段的错误嵌套列表。但是,将使用字段的文字名称。生成的html在特定字段中出现错误,可能如下所示 <ul class="errorlist"> <li> target_date_mdcy <ul class="errorlist"> <li>This field is required.&l
<ul class="errorlist">
<li>
target_date_mdcy
<ul class="errorlist">
<li>This field is required.</li>
</ul>
</li>
</ul>
-
目标日期
- 此字段为必填字段
我想使用错误列表功能,因为它很好,很简单。但是,我想使用标签(“Target Date”,比如)而不是字段名。事实上,我想不出有哪种情况下,您希望为网页用户显示字段名。有没有办法将渲染的错误列表与字段标签一起使用?我看不到一种简单的方法 表单的errors属性实际上返回一个
ErrorDict
,一个在django.forms.utils
中定义的类,它是dict
的一个子类,知道如何将自身作为unicode表示生成ul呈现。但键实际上是字段名,这对于其他行为很重要。因此,它无法轻松访问字段标签
您可以定义一个接受表单的自定义模板标记来生成您喜欢的呈现,因为在Python代码中,给定表单和字段名很容易获得字段标签。或者,您可以在视图中按标签构造错误列表,将其添加到上下文中,然后使用它
编辑
或者,您也可以遍历字段并检查它们各自的错误,同时记住显示非字段错误。比如:
<ul class="errorlist">
{% if form.non_field_errors %}
<li>{{ form.non_field_errors }}</li>
{% endif %}
{% for field in form %}
{% if field.errors %}
<li>
{{ field.label }}
<ul class="errorlist">
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>
{%if form.non_字段_错误%}
- {{form.non_field_errors}}
{%endif%}
{%形式的字段为%}
{%if field.errors%}
-
{{field.label}
{%字段中有错误。错误%}
- {{error}}
{%endfor%}
{%endif%}
{%endfor%}
您可能还希望将非字段错误包装到列表中,具体取决于。以下是我根据Peter的建议,用于呈现带有字段标签的错误列表的过滤器
from django.utils.safestring import mark_safe
from django.template import Library, Context, loader
register = Library()
@register.filter
def form_error_list(form):
result = ""
if form.errors:
fields = form.fields
error_items = []
for error_field in form.errors:
label = fields[error_field].label
if not label:
label = ' '.join([word.capitalize() for word in error_field.split('_')])
errors = form.errors[error_field]
error_li = ''.join(['<li>{0}</li>'.format(error) for error in errors])
error_items.append({'label': label, 'error_li': error_li})
inner = ''.join(['<li>{0}<ul class="errorlist">{1}</ul></li>'.format(item['label'], item['error_li']) for item in error_items])
result = mark_safe('<ul class="errorlist">{0}</ul>'.format(inner))
return result
来自django.utils.safestring导入标记\u safe
从django.template导入库、上下文、加载程序
寄存器=库()
@寄存器过滤器
def表单错误列表(表单):
result=“”
如果form.errors:
fields=form.fields
错误项=[]
对于form.errors中的error_字段:
label=字段[错误\字段]。label
如果没有标签:
label=''.join([word.capitalize()表示错误字段中的单词.split(''))
错误=表单。错误[错误\u字段]
错误_li=''.join(['{0} '.format(error)表示错误中的错误])
错误\u项。追加({'label':label'error\u li':error\u li})
inner=''.join(['{0}{1}
')。格式(错误项中的项['label',项['error\u li']))
结果=标记安全('{0}
'.format(内部))
返回结果
我知道这一点已经得到了回答,但我遇到了相同的情况,发现有一种简单的方法可以使用标签:
{% if form.errors %}
<ul class="user-msg error">
{% for field in form %}
{% for error in field.errors %}
<li>
{% if field != '__all__' %}
<strong>{{ field.label }}:</strong>
{% endif %}
{{ error }}
</li>
{% endfor %}
{% endfor %}
</ul>
{% endif %}
{%if form.errors%}
{%形式的字段为%}
{%字段中有错误。错误%}
-
{%if字段!='\uuuuu all\uuuuuu%}
{field.label}:
{%endif%}
{{error}}
{%endfor%}
{%endfor%}
{%endif%}
我在一个自定义表单类中解决了这个问题,我的所有表单都继承该类,而不是django.forms.form
。在那里,我改变了表单的工作方式。通过返回一个自定义ErrorDict
,它的as_ul
方法将标签考虑在内。因此,您不需要更改模板,但需要让表单继承CustomBaseForm
class CustomErrorDict(ErrorDict):
def __init__(self, form, iterable=None, **kwargs):
self.form = form
super(CustomErrorDict, self).__init__(iterable, **kwargs)
def as_ul(self):
if not self:
return u''
def humanify(field_name):
try:
return self.form.fields[field_name].label or field_name
except:
return field_name
# main logic is copied from the original ErrorDict:
return mark_safe(u'<ul class="errorlist">%s</ul>'
% ''.join([u'<li>%s%s</li>' % (humanify(k), force_unicode(v))
for k, v in self.items()]))
class CustomBaseForm(forms.Form):
@property
def errors(self):
return CustomErrorDict(self, super(forms.Form, self).errors)
... rest of CustomBaseForm ...
class CustomErrorDict(ErrorDict):
定义初始化(self,form,iterable=None,**kwargs):
self.form=form
超级(CustomErrorDict,self)。\uuuu初始化(iterable,**kwargs)
def as_ul(自身):
如果不是自己:
返回u“
def humanify(字段名称):
尝试:
返回self.form.fields[字段名称].标签或字段名称
除:
返回字段名称
#主逻辑从原始ErrorDict复制:
返回安全标记(u'%s
'
%''.join([u'%s%s '%(humanify(k),force_unicode(v))
对于self.items()]中的k,v)
类CustomBaseForm(forms.Form):
@财产
def错误(自我):
返回CustomErrorDict(self,super(forms.Form,self.errors)
... CustomBaseForm的其余部分。。。
来自django导入表单
定义my_清洁(自我):
self.my_errors=''
对于self.visible_字段()中的x:
如果x.0错误:
self.my_errors+=“%s:%s”%(x.label,x.errors)
类SetPwdForm(forms.Form):
pwd=forms.CharField(label='password',required=True,最小长度=6)
def清洁(自清洁):
...
我的清洁(自我)
在视图中使用myform.my\u错误。以防有人在查看时使用django.contrib.messages
框架执行类似操作,例如,在FormView
中:
def form_invalid(self, form):
for field, errors in form.errors.items():
for error in errors:
messages.error(
self.request,
form.fields[field].label + ": " + error
)
请注意,这只是一个基本模板,如果form.fields[field]
没有意义,您必须注意代码中的非字段错误等。谢谢,Peter。我不知道关于ErrorDict的事。我使用了自定义过滤器,因为我可能会继续使用它。如果您有任何非字段错误,这将引发异常-对于完整的一般情况,您将
def form_invalid(self, form):
for field, errors in form.errors.items():
for error in errors:
messages.error(
self.request,
form.fields[field].label + ": " + error
)