Ошибка визуализации формы с меткой, а не именем поля
Я хотел бы перечислить все ошибки формы вместе с помощью {{form.errors}} в шаблоне. Это создает список полей формы и вложенных списков ошибок для каждого поля. Однако используется буквальное имя поля. Сгенерированный html с ошибкой в определенном поле может выглядеть так.
<ul class="errorlist">
<li>
target_date_mdcy
<ul class="errorlist">
<li>This field is required.</li>
</ul>
</li>
</ul>
Я хотел бы использовать функцию списка ошибок, так как это приятно и легко. Тем не менее, я хочу использовать метку ( "Целевая дата", скажем), а не имя поля. На самом деле, я не могу придумать случай, в котором вы хотите, чтобы имя поля отображалось для пользователя веб-страницы. Можно ли использовать отображаемый список ошибок с меткой поля?
Ответы
Ответ 1
Я не вижу простого способа сделать это.
Атрибут ошибок формы фактически возвращает ErrorDict
, класс, определенный в django.forms.utils
- это подкласс dict
, который знает, чтобы произвести это отображение в себе как его представление в Юникоде. Но ключи на самом деле являются именами полей, и это важно для поддержания другого поведения. Таким образом, он не обеспечивает легкий доступ к меткам поля.
Вы можете определить собственный тег шаблона, который принимает форму для получения рендеринга, который вы предпочитаете, поскольку в коде 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 в списке, в зависимости.
Ответ 2
Я знаю, что это уже ответили, но я столкнулся с одним и тем же сценарием и обнаружил, что существует простой способ использования метки:
{% 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 %}
Ответ 3
Я решил это в классе пользовательской формы, который наследует все мои формы вместо 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 ...
Ответ 4
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 в представлениях.
Ответ 5
На всякий случай, если кто-то ищет что-то подобное, используя фреймворк 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]
не имеет смысла.
Ответ 6
Здесь фильтр, который я использовал для отображения списка ошибок с меткой поля, следуя предложению Питера.
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