【django】Ajaxによる非同期通信:動的にページ更新する方法
2021.03.18 /
本記事ではDjangoでAjax非同期通信を使用して、動的にページ更新する方法を解説しています。
Ajaxを使うことで、ページ遷移(ページの読み込み)を行うことなく、ページの一部のみを更新することができます。1からページを読み込むことがないため、様々なメリットが得られます。
初心者にも理解しやすいように、Ajaxについて詳しく解説しています。
Django環境の構築から、Ajaxを用いたサンプルプログラムまで解説していますので、コピペするだけでもAjaxを使ったページを作成できるようになっています。
ぜひご自分のパソコンで試してみてください。
本記事を通して以下の知識を学べます。
- Ajaxについて
- Ajaxのデータ形式(JSON)
- DjangoでのAjaxの実装方法
Ajax
Ajaxとは
Ajaxとは「Asynchronous JavaScript + XML」の略で、JavaScriptとXMLを使用してWebサーバと非同期通信を行う技術(手法)です。
具体的には、JavaScriptのHTTP通信機能を用いてWebサーバとの非同期通信を実現し、WebサーバとXMLデータをやりとりします。
非同期通信とは、コンピュータ間でデータの送信・受信のタイミングを合わさずに通信を行える通信方式。要求を出したコンピュータは、応答を待つことなく別の処理を行えます
通常、ブラウザでWebサーバと通信を行うと、ページの読み込みを1から行います。そのためユーザーはページ読み込みが終わるまで次の操作ができません。
Ajaxではページはそのままの状態でWebサーバと通信を行い、動的にページを変更します。
ページ全体の更新を行わずページの一部のみを更新できるので、スピードが速く、サーバとの通信が終わることを待たずにページ操作が可能です。
代表的なサイトとして、Googleマップがあります。Googleマップの登場により、Ajaxは世間に知られるようになりました。
Ajaxのメリット
以下にAjaxを使うことのメリットを記します。
- ページ全体の更新を行わず(ページ遷移がない)に、ページの一部のみを更新できる
- Webサーバと通信中にページ操作が可能
- ページ読み込み(ページ遷移)がないため、画面が真っ白になることがない
データ形式
もともとはXMLによるデータのやりとりを行っていました。
ですが現在では、通信時のデータ量の削減が可能なことからJSONが使用されることが一般的です。
本記事で説明するAjaxも、JSONによる非同期通信を行っています。
JSONとは、JavaScript Object Notationの略で、読み書きが簡単、軽量という特徴を持っています。
JSONのデータは以下のように記述します。
{ "name": "Office", "age": 54 }
JSONについてより詳しく学びたい方は、以下記事をご参照ください。
JSONとは?特徴や記述方法、利用される場面について
Ajaxの準備
Python環境の構築(Anacondaのインストール)
【django】Webサイト・アプリを作成するまでの一連の流れ
仮想環境の作成
【Python】仮想環境の構築と有効化の方法
Djangoのインストールおよび基本操作
【django】Webサイト・アプリを作成するまでの一連の流れ
サンプルプログラム
次のようなページをAjaxで作成してみます。
数値を入力して計算ボタンを押すと、入力した数値の足し算・引き算の結果が表示されます。
結果の表示はページが再読み込みされることなく、非同期通信により表示されます。
HTML + Ajax
<!doctype html>
<html lang="ja">
<head>
<title>Ajax</title>
</head>
<body>
<div class="container">
<h2>数値の入力</h2>
<form id="ajax-number" action="{% url 'blog:ajax_number' %}" method="POST">
{% csrf_token %}
<input type="number" id="number1" required>
<input type="number" id="number2" required>
<button type="submit" >計算</button>
</form>
<h2>数値の計算</h2>
<div class="result">
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('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);
}
}
});
$('#ajax-number').on('submit', function(e) {
e.preventDefault();
$.ajax({
'url': '{% url "blog:ajax_number" %}',
'type': 'POST',
'data': {
'number1': $('#number1').val(),
'number2': $('#number2').val(),
},
'dataType': 'json'
})
.done(function(response){
$('.result').prepend('<p>引き算結果:' + response.minus + '</p>');
$('.result').prepend('<p>足し算結果:' + response.plus + '</p>');
});
});
</script>
</body>
</html>
urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.index, name='index'),
path('ajax-number/', views.ajax_number, name='ajax_number'),
]
views.py
from django.shortcuts import render
from django.conf import settings
from django.http import JsonResponse
def index(request):
return render(request, 'index.html', {})
def ajax_number(request):
number1 = int(request.POST.get('number1'))
number2 = int(request.POST.get('number2'))
plus = number1 + number2
minus = number1 - number2
d = {
'plus': plus,
'minus': minus,
}
return JsonResponse(d)
Ajaxでの非同期通信方法
jQueryの読み込み
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Ajax前のおまじない
Ajaxによる処理を記入する前に、以下のおまじないを記入します。
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('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);
}
}
});
これはCSRFトークンの処理で、Ajax通信でデータをPOSTする場合は必ず記述しておいてください。
submitイベントを検知する
htmlファイルにAjax(jQuery)を記述していきます。
まずsubmitが押下されたら、処理が走るように次のように記述をします。
$('#ajax-number').on('submit', function(e) {
ここに処理を書く
});
form送信を防止する
フォームでsubmitが押されたときに、フォーム送信の通信を止めるためにpreventDefault()を使用します。
event.preventDefault();
Ajaxの構造
Ajaxは以下のような3つの構造(ブロック)に分かれています。
- $.ajax:サーバに送信するデータの設定
- .done:通信成功時の処理
- .fail:通信失敗時の処理
$.ajax({
サーバに送信するリクエストの設定
)}
.done(function(){
通信成功時の処理
})
.fail(function(){
通信失敗時の処理
})
サーバに送信するリクエストの設定
$.ajaxに記載する各引数について説明します。$.ajaxには次のように引数を指定します。
$.ajax({
'url': '{% url "blog:ajax_number" %}',
'type': 'POST',
'data': {
'number1': $('#number1').val(),
'number2': $('#number2').val(),
},
'dataType': 'json'
})
$.ajax関数の引数には、上記からわかるように連想配列を指定します。キーと値の組み合わせでリクエストの設定を行います。
以下に示すようなキーと値の組み合わせを指定します。
url:リクエストを送信するURLを指定
type:HTTPメソッドのGET通信かPOST通信を指定
data:サーバに送信するデータの指定
dataType:データ形式(ここではjson)を指定します。
通信成功時の処理
次のようにして、views.pyから受け取ったJSONデータをページに表示しています。
.done(function(response){
$('.result').prepend('<p>引き算結果:' + response.minus + '</p>');
$('.result').prepend('<p>足し算結果:' + response.plus + '</p>');
});
views.pyでのAjax受信データの処理
サンプルプログラムでは次のようにviews.pyで処理を行っています。
def ajax_number(request):
number1 = int(request.POST.get('number1'))
number2 = int(request.POST.get('number2'))
plus = number1 + number2
minus = number1 - number2
d = {
'plus': plus,
'minus': minus,
}
return JsonResponse(d)
Ajaxによる非同期通信で送信されたデータは、request.POST.get()を使用して取得します。
返したいデータを辞書にまとめたら、JsonResponseを使用して返します。
クライアント側でJsonResponseによるデータを受信できたら、Ajaxの構造「通信成功時の処理」が走る、という流れです。
まとめ
本記事「【Django】Ajaxによる非同期通信:動的にページ更新する方法」はいかがでしたか。
Ajaxについて知らない方にも理解しやすかったと思います。
Ajaxが使えるようになれば、作成できるWebアプリケーションの幅が非常に広がります。
ぜひ本記事を参考にして、Ajaxを使用したWebアプリケーションを作成してみてください。