Django Forms: if not valid, show form with error message Django Forms: if not valid, show form with error message django django

Django Forms: if not valid, show form with error message


If you render the same view when the form is not valid then in template you can access the form errors using form.errors.

{% 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 %}

An example:

def myView(request):    form = myForm(request.POST or None, request.FILES or None)    if request.method == 'POST':        if form.is_valid():            return HttpResponseRedirect('/thanks/')    return render(request, 'my_template.html', {'form': form})


views.py

from django.contrib import messages def view_name(request):    if request.method == 'POST':        form = form_class(request.POST)        if form.is_valid():            return HttpResponseRedirect('/thanks'/)        else:            messages.error(request, "Error")return render(request, 'page.html', {'form':form_class()})

If you want to show the errors of the form other than that not valid just put {{form.as_p}} like what I did below

page.html

<html>    <head>        <script>            {% if messages %}                {% for message in messages %}                    alert('{{message}}')                {% endfor %}            {% endif %}        </script>    </head>    <body>        {{form.as_p}}    </body></html> 


UPDATE:Added a more detailed description of the formset errors.


Form.errors combines all field and non_field_errors. Therefore you can simplify the html to this:

template

    {% load form_tags %}    {% if form.errors %}    <div class="alert alert-danger alert-dismissible col-12 mx-1" role="alert">        <div id="form_errors">            {% for key, value in form.errors.items %}                <span class="fieldWrapper">                    {{ key }}:{{ value }}                </span>            {% endfor %}        </div>        <button type="button" class="close" data-dismiss="alert" aria-label="Close">            <span aria-hidden="true">×</span>        </button>    </div>    {% endif %}If you want to generalise it you can create a list_errors.html which you include in every form template. It handles form and formset errors:    {% if form.errors %}    <div class="alert alert-danger alert-dismissible col-12 mx-1" role="alert">        <div id="form_errors">            {% for key, value in form.errors.items %}                <span class="fieldWrapper">                    {{ key }}:{{ value }}                </span>            {% endfor %}        </div>        <button type="button" class="close" data-dismiss="alert" aria-label="Close">            <span aria-hidden="true">×</span>        </button>    </div>    {% elif formset.total_error_count %}    <div class="alert alert-danger alert-dismissible col-12 mx-1" role="alert">        <div id="form_errors">            {% if formset.non_form_errors %}                {{ formset.non_form_errors }}            {% endif %}            {% for form in formset.forms %}                {% if form.errors %}                    Form number {{ forloop.counter }}:                    <ul class="errorlist">                    {% for key, error in form.errors.items %}                        <li>{{form.fields|get_label:key}}                            <ul class="errorlist">                                <li>{{error}}</li>                            </ul>                        </li>                    {% endfor %}                    </ul>                {% endif %}            {% endfor %}        </div>    </div>    {% endif %}

form_tags.py

from django import templateregister = template.Library()def get_label(a_dict, key):    return getattr(a_dict.get(key), 'label', 'No label')register.filter("get_label", get_label)

One caveat: In contrast to forms Formset.errors does not include non_field_errors.