Bentuk Django: jika tidak valid, tampilkan formulir dengan pesan kesalahan


112

I Django bentuk, itu dapat memeriksa apakah formulir itu valid:

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

Tapi saya kehilangan apa yang harus dilakukan jika tidak valid? Bagaimana cara mengembalikan formulir dengan pesan kesalahan? Saya tidak melihat "lain" di salah satu contoh.

Jawaban:


242

Jika Anda membuat tampilan yang sama ketika formulir tidak valid maka di Templat Anda dapat mengakses kesalahan formulir menggunakanform.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 %}

Sebuah contoh:

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})

Saya telah menambahkan contoh sederhana. Pastikan Anda mengikuti pendekatan yang sama yang telah saya sebutkan.
Aamir Adnan

1
Saya melihat. Saya mengembalikan formulir yang sama dengan yang saya dapatkan. Pesan kesalahan secara otomatis ditambahkan ke dalamnya oleh fungsi is_valid ().
pengguna984003

ya, Anda mengerti sekarang. Jika Anda belum membuat formulir secara manual maka kesalahan akan otomatis ditampilkan untuk setiap bidang.
Aamir Adnan

@AlexanderSupertramp myFormadalah turunan dari salah satu forms.Formatau forms.ModelForm, baca tentang Formulir Django
Aamir Adnan

Bagaimana jika saya tidak memiliki tampilan .. misalnya menggunakan formulir admin standar dalam CMS. Misalnya tentang UNIQUE constraint failed:pengecualian?
geoidesic

19

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

Jika ingin menampilkan kesalahan formulir selain yang tidak valid cukup letakkan {{form.as_p}} seperti yang saya lakukan di bawah ini

page.html

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

Lalu apa yang harus saya kembalikan? Bagaimana ini bisa sampai ke template saya?
pengguna984003

Saya memperbarui kode saya. Anda juga dapat meletakkan for loop message di template Anda sebagai gantinya dalam skrip, jika Anda mau.
Catherine

1
ini adalah pendekatan yang keren - tetapi perlu waspada ('{{message}}');
amchugh89

Bagaimana Anda menempatkan sesuatu yang lebih deskriptif dalam pesan kesalahan dari tampilan daripada 'Kesalahan' seperti yang telah Anda lakukan messages.error(request, "Error")?
cbuch1800

3
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})

3

UPDATE: Menambahkan deskripsi yang lebih mendetail tentang kesalahan formset.


Form.errors menggabungkan semua field dan non_field_errors. Oleh karena itu Anda dapat menyederhanakan html menjadi ini:

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">&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)

Satu peringatan: Berbeda dengan form, Formset.errors tidak menyertakan non_field_errors.


0

Anda bisa melakukan seperti ini karena ketika Anda menginisialisasi formulir di berisi data formulir dan data tidak valid juga:

def some_func(request):
    form = MyForm(request.POST)
    if form.is_valid():
         //other stuff
    return render(request,template_name,{'form':form})

jika akan memunculkan kesalahan di templat jika ada tetapi data formulir akan tetap seperti:

error_demo_di sini


-1

Anda dapat menempatkan variabel flag, dalam hal ini berhasil .

def preorder_view(request, pk, template_name='preorders/preorder_form.html'):
    is_successed=0
    formset = PreorderHasProductsForm(request.POST)
    client= get_object_or_404(Client, pk=pk)
    if request.method=='POST':
        #populate the form with data from the request
       # formset = PreorderHasProductsForm(request.POST)
        if formset.is_valid():
            is_successed=1
            preorder_date=formset.cleaned_data['preorder_date']
            product=formset.cleaned_data['preorder_has_products']
            return render(request, template_name, {'preorder_date':preorder_date,'product':product,'is_successed':is_successed,'formset':formset})



    return render(request, template_name, {'object':client,'formset':formset})

setelah itu di template Anda, Anda tinggal memasukkan kode di bawah ini

{%if is_successed == 1 %}
<h1>{{preorder_date}}</h1>
<h2> {{product}}</h2>
{%endif %}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.