แบบฟอร์ม Django: หากไม่ถูกต้องให้แสดงแบบฟอร์มพร้อมข้อความแสดงข้อผิดพลาด


114

แบบฟอร์ม I Django สามารถตรวจสอบว่าแบบฟอร์มถูกต้องหรือไม่:

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

แต่ฉันพลาดที่จะทำอย่างไรถ้ามันไม่ถูกต้อง? ฉันจะส่งคืนแบบฟอร์มพร้อมข้อความแสดงข้อผิดพลาดได้อย่างไร ฉันไม่เห็น "else" ในตัวอย่างใด ๆ

คำตอบ:


246

หากคุณแสดงมุมมองเดียวกันเมื่อฟอร์มไม่ถูกต้องแล้วในแม่แบบที่คุณสามารถเข้าถึงข้อผิดพลาดแบบฟอร์มที่ใช้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 %}

ตัวอย่าง:

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

ฉันได้เพิ่มตัวอย่างง่ายๆ ตรวจสอบให้แน่ใจว่าคุณปฏิบัติตามแนวทางเดียวกับที่ฉันได้กล่าวถึง
Aamir Adnan

1
ฉันเห็น. ฉันส่งคืนรูปแบบเดียวกับที่ฉันได้รับข้อความแสดงข้อผิดพลาดถูกเพิ่มโดยอัตโนมัติโดยฟังก์ชัน is_valid ()
user984003

ใช่คุณเข้าใจแล้ว หากคุณไม่ได้แสดงแบบฟอร์มด้วยตนเองข้อผิดพลาดจะแสดงโดยอัตโนมัติสำหรับแต่ละฟิลด์
Aamir Adnan

@AlexanderSupertramp myFormเป็นตัวอย่างforms.Formหรือforms.ModelFormอ่านเกี่ยวกับDjango Forms
Aamir Adnan

จะเกิดอะไรขึ้นถ้าฉันไม่มีมุมมอง .. เช่นใช้แบบฟอร์มผู้ดูแลระบบมาตรฐานใน CMS ตัวอย่างเช่นในUNIQUE constraint failed:ข้อยกเว้น?
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()})

หากคุณต้องการแสดงข้อผิดพลาดของแบบฟอร์มอื่นนอกเหนือจากที่ไม่ถูกต้องให้ใส่ {{form.as_p}} เหมือนที่ฉันทำด้านล่าง

page.html

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

แล้วฉันจะกลับอะไร? สิ่งนี้มาถึงแม่แบบของฉันได้อย่างไร
user984003

ฉันอัปเดตรหัสของฉัน คุณยังสามารถใส่สำหรับข้อความวนซ้ำในเทมเพลตของคุณแทนในสคริปต์ได้หากต้องการ
catherine

1
นี่เป็นแนวทางที่ยอดเยี่ยม แต่ต้องแจ้งเตือน ('{{message}}');
amchugh89

คุณจะใส่คำอธิบายในข้อความแสดงข้อผิดพลาดจากมุมมองมากกว่า 'ข้อผิดพลาด' ได้messages.error(request, "Error")อย่างไร?
cbuch1800

4

อัปเดต: เพิ่มคำอธิบายโดยละเอียดเพิ่มเติมเกี่ยวกับข้อผิดพลาดของ formet


Form.errors รวมฟิลด์ทั้งหมดและ non_field_errors ดังนั้นคุณสามารถลดความซับซ้อนของ html เป็น:

แม่แบบ

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

หนึ่งข้อแม้: ตรงกันข้ามกับ Formset.errors ไม่รวม non_field_errors


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

0

คุณสามารถทำเช่นนี้ได้เพราะเมื่อคุณเริ่มต้นฟอร์มในประกอบด้วยข้อมูลแบบฟอร์มและข้อมูลที่ไม่ถูกต้องเช่นกัน:

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

ถ้าจะเพิ่มข้อผิดพลาดในเทมเพลตถ้ามี แต่ข้อมูลฟอร์มจะยังคงเป็น:

error_demo_here


0

คำตอบของ @ AamirAdnan หายไปfield.label; อีกวิธีหนึ่งในการแสดงข้อผิดพลาดในไม่กี่บรรทัด

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

-1

คุณสามารถใส่เพียงตัวแปรธงในกรณีนี้is_successed

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

หลังจากนั้นในเทมเพลตของคุณคุณสามารถใส่รหัสด้านล่าง

{%if is_successed == 1 %}
<h1>{{preorder_date}}</h1>
<h2> {{product}}</h2>
{%endif %}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.