Добавление ошибок в ошибки формы Django.__ all__

Как добавить ошибки в верхнюю часть формы после очистки данных? У меня есть объект, который должен выполнить вызов REST для внешнего приложения (карты Google) в качестве условия предварительного сохранения, и это может не произойти, а это значит, что мне нужно, чтобы мои пользователи исправили данные в форме. Поэтому я очищаю данные, а затем пытаюсь сохранить и добавить в форму ошибки, если сохранение не работает:

if request.method == "POST":
#clean form data
    try:
        profile.save()
        return HttpResponseRedirect(reverse("some_page", args=[some.args]))
    except ValueError:
        our_form.errors.__all__ = [u"error message goes here"]
return render_to_response(template_name, {"ourform": our_form,}, 
       context_instance=RequestContext(request))

Не удалось вернуть текст ошибки в моих модульных тестах (которые искали его в {{form.non_field_errors}}), а затем, когда я запускал его через отладчик, ошибки не были добавлены в сообщение об ошибке формы, когда они достичь линии render_to_response, нигде больше в дереве our_form. Почему это не сработало? Как я должен добавить ошибки в верхней части формы после очистки?

Ответ 1

Вы действительно хотите сделать это во время проверки формы и поднять ValidationError оттуда... но если вы настроитесь на это, вы захотите получить доступ к _errors для добавления новых сообщений. Попробуйте что-то вроде этого:

from django.forms.util import ErrorList

our_form._errors["field_name"] = ErrorList([u"error message goes here"])

Ответ 2

Неполевые ошибки могут быть добавлены с помощью константного словаря NON_FIELD_ERRORS (по умолчанию это __all__):

from django import forms
errors = my_form._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.util.ErrorList())
errors.append("My error here")

Ответ 3

В Django 1.7 или выше я бы сделал:

form.add_error(field_name, "Some message")

Метод add_error был добавлен в 1.7. Переменная form - это форма, которую я хочу манипулировать, и field_name - это имя конкретного поля или None, если мне нужна ошибка, которая не связана с определенным полем.

В Django 1.6 я бы сделал что-то вроде:

from django.forms.forms import NON_FIELD_ERRORS

errors = form._errors.setdefault(field_name, form.error_class())
errors.append("Some message")

В приведенном выше коде form - это форма, которую я хочу обработать, и field_name - это имя поля, для которого я хочу добавить ошибку. field_name может быть установлено на NON_FIELD_ERRORS, чтобы добавить ошибку, не связанную с определенным полем. Я использую form.error_class() для создания пустого списка сообщений об ошибках. Так Django 1.6 создает пустой список, а не создает экземпляр ErrorList() напрямую.

Ответ 4

Вы должны поднять validationerror.

Почему бы не поместить проверку в виде чистого метода

class ProfileForm(forms.Form):
    def clean(self):
        try:
            #Make a call to the API and verify it works well
        except:
            raise forms.ValidationError('Your address is not locatable by Google Maps')

таким образом вам просто нужен стандартный form.is_valid() в представлении.

Ответ 5

Ты почти там с оригинальным решением. Вот базовый класс формы, который я построил, что позволяет мне делать то же самое, т.е. Добавлять сообщения об ошибках в поле:

from django import forms
from django.forms.util import ErrorDict
from django.forms.forms import NON_FIELD_ERRORS 

class MyBaseForm(forms.Form):
    def add_form_error(self, message):
        if not self._errors:
            self._errors = ErrorDict()
        if not NON_FIELD_ERRORS in self._errors:
            self._errors[NON_FIELD_ERRORS] = self.error_class()
        self._errors[NON_FIELD_ERRORS].append(message)

class MyForm(MyBaseForm):
    ....

Все мои формы расширяют этот класс, поэтому я могу просто вызвать метод add_form_error(), чтобы добавить другое сообщение об ошибке.

Ответ 6

Я не уверен, насколько ужасен этот хак (я только работал над двумя проектами Django до этого момента), но если вы сделаете что-то вроде этого, вы получите отдельное сообщение об ошибке, которое не связано с конкретное поле в модели:

form = NewPostForm()
if something_went_horribly_wrong():
  form.errors[''] = "You broke it!"

Ответ 7

Если проверка относится к слою данных, то вы действительно не должны использовать проверку формы. С Django 1.2, однако, существует аналогичная концепция для моделей Django, и это, безусловно, то, что вы используете. См. документацию для проверки модели.