Biểu mẫu Django: nếu không hợp lệ, hiển thị biểu mẫu có thông báo lỗi


112

I Django biểu mẫu, nó có thể kiểm tra xem biểu mẫu có hợp lệ hay không:

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

Nhưng tôi thiếu phải làm gì nếu nó không hợp lệ? Làm cách nào để trả lại biểu mẫu có thông báo lỗi? Tôi không thấy "else" trong bất kỳ ví dụ nào.

Câu trả lời:


242

Nếu bạn hiển thị cùng một dạng xem khi biểu mẫu không hợp lệ thì trong mẫu, bạn có thể truy cập các lỗi biểu mẫu bằng cách sử dụngform.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 %}

Một ví dụ:

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

Tôi đã thêm một ví dụ đơn giản. Hãy chắc chắn rằng bạn đang làm theo cùng một cách tiếp cận mà tôi đã đề cập.
Aamir Adnan

1
Tôi hiểu rồi. Tôi trả lại cùng một biểu mẫu mà tôi đã nhập. Các thông báo lỗi đã tự động được thêm vào nó bởi hàm is_valid ().
user984003

vâng bạn đã hiểu nó ngay bây giờ. Nếu bạn chưa kết xuất biểu mẫu theo cách thủ công thì lỗi sẽ tự động hiển thị cho từng trường.
Aamir Adnan

@AlexanderSupertramp myFormlà một ví dụ của một trong hai forms.Formhoặc forms.ModelForm, đọc về Django Forms
Aamir Adnan

Điều gì xảy ra nếu tôi không có chế độ xem .. ví dụ: sử dụng biểu mẫu quản trị viên tiêu chuẩn trong CMS. Ví dụ về một UNIQUE constraint failed:ngoại lệ?
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()})

Nếu bạn muốn hiển thị các lỗi của biểu mẫu khác với biểu mẫu không hợp lệ, chỉ cần đặt {{form.as_p}} như những gì tôi đã làm bên dưới

page.html

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

Và sau đó tôi trở về là gì? Làm thế nào để điều này đến với mẫu của tôi?
user984003

Tôi cập nhật mã của mình. Bạn cũng có thể đặt thông điệp vòng lặp for trong mẫu của mình thay vì trong tập lệnh, nếu bạn muốn.
catherine

1
đây là một cách tiếp cận hay - nhưng cần phải cảnh giác ('{{message}}');
amchugh89

Làm thế nào bạn sẽ đặt một cái gì đó mô tả hơn trong thông báo lỗi từ chế độ xem hơn là 'Lỗi' như bạn đã làm 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

CẬP NHẬT: Đã thêm mô tả chi tiết hơn về các lỗi của bộ định dạng.


Form.errors kết hợp tất cả trường và non_field_errors. Do đó, bạn có thể đơn giản hóa html thành:

bản mẫu

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

Một lưu ý: Ngược lại với các biểu mẫu, Formset.errors không bao gồm non_field_errors.


0

đơn giản bạn có thể làm như vậy vì khi bạn khởi tạo biểu mẫu trong cũng chứa dữ liệu biểu mẫu và dữ liệu không hợp lệ:

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

if sẽ làm tăng lỗi trong mẫu nếu có nhưng dữ liệu biểu mẫu sẽ vẫn như sau:

error_demo_here


-1

Bạn có thể đặt đơn giản là một biến cờ, trong trường hợp này là thành công .

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

sau đó trong mẫu của bạn, bạn chỉ cần đặt mã bên dưới

{%if is_successed == 1 %}
<h1>{{preorder_date}}</h1>
<h2> {{product}}</h2>
{%endif %}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.