巳年じゃないけど Python やろうぜ(その 19)
Ajax の活用
以前作成した customer_search アプリケーションを Ajax を活用して作り変えてみましょう。
Ajax 活用のための準備
Ajax 活用のために、いくつかの準備が必要です。
1. js.cookie.js をダウンロードする
GitHub - js-cookie/js-cookie: A simple, lightweight JavaScript API for handling browser cookies
上記サイトから js.cookie.js をダウンロードします。間違っても script 要素の src 属性に URL を直接打ち込まないように(GitHub は CDN ではありません !)。
持って来た js.cookie.js は django_test/customer_search/static/customer_search/js/
に保存します。
2. csrf_token.js の作成
以下の内容で django_test/customer_search/static/customer_search/js/
内に csrf_token.js
を作成します。ほぼ公式ドキュメントからのコピペです。
var csrftoken = Cookies.get('csrftoken'); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader('X-CSRFToken', csrftoken); } } });
django_test/customer_search/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); } ); });
かなり雑に書いてますがとりあえず。
4. テンプレート内でスクリプトを呼ぶ
{% 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.1.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' %}"> <!-- form 内は変更しないので省略 --> </form> <script src="{% static 'customer_search/js/search.js' %}"></script> </body> </html>
5. urls.py の修正
url 逆引きの設定も含めて書き換え。
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_ajax, name='search'), ]
6. 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_ajax(request): customer_id = request.POST['customer_id'] try: customer = Customer.objects.get(pk=customer_id) data = { 'customer_name': customer.name, 'customer_phone': customer.phone, } except Customer.DoesNotExist: message = _('No data!') data = { 'customer_name': message, 'customer_phone': message, } return JsonResponse(data)
送りたいデータを辞書形式にして JsonResponse で送信するだけ。いろいろ調査しましたがこれが一番簡単のようです。
課題
フォームのバリデーションをどうするか。現状では不正な値を入力したときに特に何も起きない。