Django Forms : 유효하지 않은 경우 오류 메시지와 함께 양식 표시


112

나는 Django 양식, 양식이 유효한지 확인할 수 있습니다.

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

하지만 유효하지 않은 경우 어떻게해야하나요? 오류 메시지가있는 양식을 어떻게 반환합니까? 예제에서 "else"가 보이지 않습니다.

답변:


242

양식이 유효하지 않을 때 동일한보기를 렌더링하면 템플릿에서를 사용하여 양식 오류에 액세스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 2013

1
내가 참조. 내가받은 것과 같은 양식을 반환합니다. 오류 메시지는 is_valid () 함수에 의해 자동으로 추가되었습니다.
user984003 2013-02-01

네, 바로 지금 얻었습니다. 양식을 수동으로 렌더링하지 않은 경우 각 필드에 대해 오류가 자동으로 표시됩니다.
Aamir Adnan 2013

@AlexanderSupertramp는 myForm하나의 인스턴스 forms.Form또는 forms.ModelForm, 읽어 장고 양식
아미르 아드 난

보기가없는 경우에는 어떻게합니까. 예를 들어 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 2013-02-01

내 코드를 업데이트합니다. 원하는 경우 스크립트 대신 템플릿에 for 루프 메시지를 넣을 수도 있습니다.
catherine 2013

1
이것은 멋진 접근 방식이지만 alert ( '{{message}}');
amchugh89

보기에서 오류 메시지에 '오류'보다 더 설명적인 것을 어떻게 넣 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

업데이트 : 폼셋 오류에 대한 자세한 설명이 추가되었습니다.


Form.errors는 모든 필드와 non_field_error를 결합합니다. 따라서 다음과 같이 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를 포함하지 않습니다.


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


-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.