12

我想在模板中使用 {{ form.errors }} 列出所有表单错误。这会生成表单字段列表和每个字段的错误嵌套列表。但是,使用字段的文字名称。生成的特定字段中有错误的 html 可能如下所示。

<ul class="errorlist">
    <li>
        target_date_mdcy
        <ul class="errorlist">
            <li>This field is required.</li>
        </ul>
    </li>
</ul>

我想使用错误列表功能,因为它既好又简单。但是,我想使用标签(例如“目标日期”)而不是字段名称。实际上,我想不出您希望为网页用户显示字段名称的情况。有没有办法将渲染的错误列表与字段标签一起使用?

4

7 回答 7

9

我没有看到一个简单的方法来做到这一点。

表单的 errors 属性实际上返回一个ErrorDict,一个定义在中的类django.forms.utils- 它是一个dict知道将自身的 ul 渲染生成为其 unicode 表示的子类。但是键实际上是字段名称,这对于维护其他行为很重要。因此,它无法轻松访问字段标签。

您可以定义一个接受表单的自定义模板标签来生成您喜欢的渲染,因为在 Python 代码中,很容易在给定表单和字段名称的情况下获取字段标签。或者您可以在视图中按标签构建错误列表,将其添加到您的上下文中,然后使用它。

再次编辑 交替,您可以遍历字段并检查它们的各个错误,记住也要显示non_field_errors。就像是:

<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>

您可能还想将 non_field_errors 包装在列表中,具体取决于。

于 2013-05-09T19:40:52.480 回答
9

我知道这已经得到了回答,但是,我遇到了同样的情况,发现有一种使用标签的简单方法:

{% 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 %}
于 2014-03-12T07:53:11.637 回答
2

我在一个自定义表单类中解决了这个问题,我的所有表单都继承而不是django.forms.Form. form.errors在那里,我通过返回一个将标签考虑在内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 ...
于 2015-03-11T09:41:27.290 回答
2
from django import forms

def my_clean(self):
    self.my_errors = ''
    for x in self.visible_fields():
        if x.errors:
            self.my_errors += "<p>%s: %s</p>" % (x.label, x.errors)


class SetPwdForm(forms.Form):
    pwd= forms.CharField(label='password', required=True, min_length=6)
    def clean(self):
        ...
        my_clean(self)

在视图中使用myform.my_errors

于 2016-02-22T08:41:02.300 回答
0

以下方法显示verbose_name而不是字段名称。它也可以使用,get_context_data()但就个人而言,我更喜欢这种方式:

from django.core.exceptions import FieldDoesNotExist


class ShowVerboseNameInFormsMixin:

    def add_error(self, field, error):
        super(ShowVerboseNameInFormsMixin, self).add_error(field, error)
        for field, message in self._errors.copy().items():
            try:
                verbose_name = self._meta.model._meta.get_field(field).verbose_name
                del self._errors[field]
                self._errors[verbose_name] = self.error_class()
                self._errors[verbose_name].extend(message)
            except FieldDoesNotExist:
                pass

然后像这样使用它:

from django import forms


class FooForm(ShowVerboseNameInFormsMixin, forms.ModelForm):
    class Meta:
        model = Foo
        fields = ['foo', 'bar', 'baz']

使用一些额外的代码,它可以显示__all__toall或任何其他预期的字符串。

于 2021-08-02T13:19:26.543 回答
0

以防万一有人正在寻找使用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]请注意,这只是一个基本模板,在没有意义的情况下,您必须处理代码中的非字段错误等。

于 2016-12-12T14:22:27.690 回答
-1

这是我按照彼得的建议使用字段标签呈现错误列表的过滤器。

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
于 2013-05-10T13:27:33.877 回答