140 votes

Django Forms : si le formulaire n'est pas valide, afficher un message d'erreur

Dans les formulaires Django, il peut vérifier si le formulaire est valide :

if form.is_valid(): 
    return HttpResponseRedirect('/thanks/')

Mais je ne sais pas quoi faire s'il n'est pas valide ? Comment renvoyer le formulaire avec les messages d'erreur ? Je ne vois pas le "else" dans aucun des exemples.

22voto

catherine Points 9634

vues.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()})

Si vous voulez montrer les erreurs du formulaire autres que celles qui ne sont pas valides, il suffit de mettre {{form.as_p}} comme ce que j'ai fait ci-dessous

page.html

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

5voto

P. Maino Points 103

UPDATE : Ajout d'une description plus détaillée des erreurs du jeu de formulaires.


Form.errors combine toutes les erreurs de champ et de non-champ. Par conséquent, vous pouvez simplifier le html à ceci :

modèle

    {% 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">&times;</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">&times;</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 template

register = template.Library()

def get_label(a_dict, key):
    return getattr(a_dict.get(key), 'label', 'No label')

register.filter("get_label", get_label)

Un avertissement : Contrairement aux formulaires, Formset.errors ne comprend pas les erreurs non_field_errors.

4voto

Lukasz Koziara Points 2052
def some_view(request):
    if request.method == 'POST':
        form = SomeForm(request.POST)
        if form.is_valid():
            return HttpResponseRedirect('/thanks'/)
    else:
        form = SomeForm()
    return render(request, 'some_form.html', {'form': form})

4voto

chalist Points 672

Cette réponse est correcte mais présente un problème : les champs ne sont pas définis. Si vous avez plus d'un champ, vous ne pouvez pas reconnaître celui qui a une erreur.

avec cette modification, vous pouvez afficher le nom du champ :

{% if form.errors %}
    {% for field in form %}
        {% for error in field.errors %}
            <div class="alert alert-danger">
                <strong>{{ field.label }}</strong><span>{{ 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 %}

2voto

Réponse manquante de @AamirAdnan field.label ; l'autre façon de montrer les erreurs en quelques lignes.

{% if form.errors %}
    <!-- Error messaging -->
    <div id="errors">
        <div class="inner">
            <p>There were some errors in the information you entered. Please correct the following:</p>
            <ul>
                {% for field in form %}
                    {% if field.errors %}<li>{{ field.label }}: {{ field.errors|striptags }}</li>{% endif %}
                {% endfor %}
            </ul>
        </div>
    </div>
    <!-- /Error messaging -->
{% endif %}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X