Angela
Angela

Reputation: 1731

How to append error message to form.non_field_errors in django?

I have a form with several fields. I have separate validation checks for each field, done via the forms validation. I however also need to check if few fields are filled in before redirecting the user to a different view. I was hoping I could somehow append the error to forms.non_field_errors as it is not for a particular field , but I am not sure what the right syntax for this would be. I have checked online and found..

form.errors['__all__'] = form.error_class(["error msg"])

This displays the error message, but it seems to mess up the other pages as well and displyas the error message if I click on anything else.

I tried

form._errors[NON_FIELD_ERRORS] = form.error_class()

This causes a 'NoneType' object has no attribute 'setdefault' error for me.

I have tried

form.non_field_errors().append("Please complete your profile in order to access the content.")

This doesn't seem to do anything and I cant see the error message on the view.

What would be the best way to do this? Ideally I dont' want to do it in the form's clean method. I feel like I should be able to append an error to the form in the view.

Upvotes: 9

Views: 13432

Answers (4)

CallMarl
CallMarl

Reputation: 593

On form there is method add_error.

class ExampleForm(forms.Form) :

    def clean(self) :
        self.add_error(None, "The __all__ error message")
        return super().clean()

The first param of add_error() function is about the refered fields. If the field is None the add_error() function will considere that the error is a form_error.

The clean() method is a hook called by _clean_form(). Then the _clean_form() function is called by full_clean(). See more: full_clean() source

Upvotes: 1

asaji
asaji

Reputation: 398

This is a bit out-dated but i recently ran into the same question and wanted to shed some further light on this for future readers.

  1. As of Django 1.6+ the errors dictionary is stored as form.errors and not form._errors
  2. If you instantiate form.is_valid(), it is the equivalent of running full_clean()
  3. NON_FIELD_ERRORS isn't necessary to import, you can simply refer to its default dictionary key of __all__

Example:

if form.is_valid():
    form.errors['__all__'] = form.error_class(['Your Error Here!'])

Upvotes: 5

user2732686
user2732686

Reputation: 474

self._errors.setdefault('__all__', ErrorList()).extend([""])

Upvotes: -1

jpic
jpic

Reputation: 33420

  1. Call full_clean(), this should initialize form._errors. This step is critical, if you don't do it, it won't work.

  2. Make the error list, it takes a list of messages, instanciate it as such: error_list = form.error_class(['your error messages'])

  3. Assign the error list to NON_FIELD_ERRORS, you have to import NON_FIELD_ERRORS from django.forms.forms, then assign as such: form._errors[NON_FIELD_ERRORS] = error_list

Here is a demonstration from a shell:

In [1]: from bet.forms import BetForm

In [2]: from django.forms.forms import NON_FIELD_ERRORS

In [3]: form = BetForm()

In [4]: form.full_clean()

In [5]: form._errors[NON_FIELD_ERRORS] = form.error_class(['your error messages'])

In [6]: form.non_field_errors()
Out[6]: [u'your error messages']

Upvotes: 18

Related Questions