巳年じゃないけど Python やろうぜ(その 20)
Ajax の活用(続き)
バリデーションエラーの出力
フォームのバリデーションエラーに関する情報は form.errors
に辞書形式で格納されているので、それを利用すれば行けることがわかりました。
views.py
from django.shortcuts import render from django.http.response import JsonResponse from django.utils.translation import ugettext as _ from .forms import CustomerForm from .models import Customer # Create your views here. def index(request): form = CustomerForm(label_suffix='') return render(request, 'customer_search/search.html', { 'form': form, }) def search(request): form = CustomerForm(request.POST) if form.is_valid(): customer_id = request.POST['customer_id'] try: customer = Customer.objects.get(pk=customer_id) customer_name = customer.name customer_phone = customer.phone except Customer.DoesNotExist: customer_name = _('No data!') customer_phone = _('No data!') else: customer_name = _('Error!') customer_phone = _('Error!') return JsonResponse({ 'customer_name': customer_name, 'customer_phone': customer_phone, 'errors': form.errors, })
メソッド名が微妙に変わってるので、対応して urls.py
も修正しておきます。
from django.conf.urls import url from . import views app_name = 'customer_search' urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^search/$', views.search, name='search'), ]
templates/customer_search/search.html
{% load static i18n %} {% trans 'customer search' as page_title %} <!doctype html> <html> <head> <title>{{ page_title | title }}</title> <link rel="stylesheet" href="{% static 'customer_search/css/search.css' %}"> <script src="//code.jquery.com/jquery-3.2.0.min.js"></script> <script src="{% static 'customer_search/js/js.cookie.js' %}"></script> <script src="{% static 'customer_search/js/csrf_token.js' %}"></script> </head> <body> <h1>{{ page_title | title }}</h1> <form method="post" action="{% url 'customer_search:search' %}"> {% csrf_token %} <table> {% for field in form %} <tr> <th>{{ field.label_tag }}</th> <td> {{ field }} <span class="error" id="{{ field.html_name }}_errors"></span> </td> </tr> {% endfor %} </table> <input type="submit" value="{% trans 'Search' %}"> </form> <script src="{% static 'customer_search/js/search.js' %}"></script> </body> </html>
span 要素は DOM で追加する方がスマートかなと思ったけど、やってみると意外に苦戦した*1ので、とりあえずこうしておきます。
static/customer_search/js/search.js
$('form').submit(function (event) { event.preventDefault(); $.post( $('form').attr('action'), { 'customer_id': $('#id_customer_id').val() }, function (res) { $('#id_customer_name').val(res.customer_name); $('#id_customer_phone').val(res.customer_phone); var errors = res.errors; var messages = []; if(!$.isEmptyObject(errors)) { messages = errors.customer_id; } $('#customer_id_errors').text(messages.join('')); } ); });
エラーメッセージはフォームのフィールド名ごとに配列で格納されているので、join
で連結*2します。
画面遷移が発生していないことが確認できます。