Getting a list of errors in a Django form

42,112

Solution 1

form.errors is a dictionary. When you do {% for error in form.errors %} error corresponds to the key.

Instead try

{% for field, errors in form.errors.items %}
    {% for error in errors %}
...

Etc.

Solution 2

Dannys's answer is not a good idea. You could get a ValueError.

{% if form.errors %}
      {% for field in form %}

           {% for error in field.errors %}
                {{field.label}}: {{ error|escape }}
           {% endfor %}

      {% endfor %}
{% endif %}

Solution 3

If you want something simple with a condition take this way :

{% if form.errors %}
  <ul>
    {% for error in form.errors %} 
      <li>{{ error }}</li>
    {% endfor %}
  </ul>
{% endif %}  

If you want more info and see the name and the error of the field, do this:

{% if form.errors %}
  <ul>
    {% for key,value in form.errors.items %} 
      <li>{{ key|escape }} : {{ value|escape }}</li>
    {% endfor %}
  </ul>
{% endif %}

If you want to understant form.errors is a big dictionary.

Solution 4

You can use this code:

{% if form.errors %}
    {% for field in form %}
        {% for error in field.errors %}
            <div class="alert alert-danger">
                <strong>{{ error|escape }}</strong>
            </div>
        {% endfor %}
    {% endfor %}

    {% for error in form.non_field_errors %}
        <div class="alert alert-danger">
            <strong>{{ error|escape }}</strong>
        </div>
    {% endfor %}

{% endif %}

this add https://docs.djangoproject.com/en/3.0/ref/forms/api/#django.forms.Form.non_field_error

Share:
42,112
icktoofay
Author by

icktoofay

Interests: binary reverse engineering, vulnerability research compilers, performance optimization functional programming, type theory Currently doing performance optimization work at a machine-learning computer-vision startup. Now we just need blockchain and we'll be set for buzzwords. ☺️

Updated on July 24, 2020

Comments

  • icktoofay
    icktoofay almost 4 years

    I'm trying to create a form in Django. That works and all, but I want all the errors to be at the top of the form, not next to each field that has the error. I tried looping over form.errors, but it only showed the name of the field that had an error, not an error message such as "Name is required."

    This is pretty much what I'd like to be able to use at the top of the form:

    {% if form.??? %}
        <ul class="errorlist">
        {% for error in form.??? %}
            <li>{{ error }}</li>
        {% endfor %}
        </ul>
    {% endif %}
    

    What would I use for ??? there? It's not errors; that just outputs the names of the fields.

  • icktoofay
    icktoofay over 14 years
    When doing this, it outputs a list with four items, each containing one character: "s", "a", "a", and "m". The specific form I'm using is the registration form in django-registration.
  • icktoofay
    icktoofay over 14 years
    After debugging this a bit, "s", "a", "a", and "m" are the second letter of the name of the fields. That's somewhat odd, but I'll mark your answer as the answer, since I think I'll be able to figure it out from here.
  • Travis Bradshaw
    Travis Bradshaw over 14 years
    Probably just need to call .items() on the dictionary, that returns a sequence of tuples of (key, value) that will unpack into your (field, errors).
  • icktoofay
    icktoofay over 4 years
    Could you elaborate on what kind of ValueError the other answer risks? I asked this question, oh, nine years ago, so I don't have the code handy to test any more, but if I recall, the accepted answer worked at the time.