【Django】Ajaxでファイルをサーバーへ送信・受信(views.pyで処理)する方法
2021.10.01 /
本記事ではDjangoのAjaxを利用した、ファイルを送信(アップロード)・受信(views.pyで処理)する方法について解説していきます。
会社で使用しているWebアプリケーションを改修しているときに、Ajaxでページ遷移を行うことなくユーザーのアップロードしたファイルをサーバーに送信し、サーバー側で処理した結果をサイト上に表示したいことがありました。
本記事ではその際に利用した以下の方法を解説していきます。
- Ajaxでファイルをサーバーに送信する方法
- Ajaxで送信されたファイルをviews.pyで処理する方法
DjangoにおけるAjax
Ajaxとは
Ajax(Asynchronous JavaScript + XML)とは、Webサーバーと非同期通信を行うための技術のことです。
Ajaxによりページ遷移(ページの読み込み)をすることなく、Webサイト上からサーバーにデータを送信することができます。またページの再読み込みなしで、ページの一部を更新することができます。
やり取りする上で使用するデータ形式はJSONです。
JSONについて知らない方は以下記事をご参照ください。
JSONとは?特徴や記述方法、利用される場面について
DjangoでAjaxを実装する方法
PythonのWebフレームワークであるDjangoでも、もちろんAjaxを実装することができます。
DjangoにAjaxを実装する詳しい方法については以下記事をご参照ください。
【django】Ajaxによる非同期通信:動的にページ更新する方法
Ajax:ファイルデータをサーバーに送信する
フォームにアップロードされたファイルをAjaxでサーバーに送信する方法を解説していきます。
フォーム(HTML)
ここでは次のフォームを利用します。
<form id="ajax-file-send" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>ファイル:<input type="file" id="uploadfile" name="uploadfile" value=""></p>
<p><input type="submit" name="submit"></p>
</form>
このファイルを送信するフォームで重要なのは次の点です。
- メソッドはPOSTとする
- Content-Typeはmultipart/form-dataとする
- CSRF対策として、{% csrf_token %}は必ず入れる
urls.py
ここではアプリケーションフォルダ内のurls.pyに次のようルーティングを記述しました。
path('ajax-file-send/', views.ajax_file_send, name='ajax_file_send')
views.py
ここではアプリケーションフォルダ内のviews.pyに次のように処理を記述しています。
def ajax_file_send(request):
print("OK")
d = {}
return JsonResponse(d)
この段階では、まだ送信されたファイルを受け取る記述はしていません。
Ajaxのソースコード
jQeryを利用できるように次のコードでjQeryを読み込みます。
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
次にDjangoで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);
}
}
});
次にファイルを送信するAjaxの本体を次のように記述します。
$('#ajax-file-send').on('submit', function(e) {
e.preventDefault();
var fd = new FormData($("#ajax-file-send").get(0));
$.ajax({
'url': '{% url "ajax_file_send" %}',
'type': 'POST',
'data': fd,
'processData': false,
'contentType': false,
'dataType': 'json'
})
.done(function(response){
//Ajax通信が成功した場合に実行する処理
});
});
Ajaxの解説
上記のAjaxについて解説していきます。
まずは送信ボタン(formのidがajax-file-send)がクリックされた時に検知し、処理を実行するjQueryを記述します。
$('#ajax-file-send').on('submit', function(e) {処理を記述}
次にフォーム送信の通信を止めるためにpreventDefault()を使用します。
e.preventDefault();
Ajaxでファイルを送信するためにFormDataオブジェクトを作成します。
FormDataを使うことでフォームに入力されたデータを一括でサーバーに送信できます。値はキーと値のペアです。
new FormData()の引数にはform要素のDOMを指定し、生成されたFormDataオブジェクトをfdに格納します。
var fd = new FormData($("#ajax-file-send").get(0));
生成したFormDataオブジェクトをAjaxを通して次のようにサーバーに送信します。
$.ajax({
'url': '{% url "ajax_file_send" %}',
'type': 'POST',
'data': fd,
'processData': false,
'contentType': false,
'dataType': 'json'
})
dataにはFormDataオブジェクトを指定します。
重要な点として、processDataとcontentTypeをfalseにしている点です。
processDataはdataを文字列への変換の有無(クエリ文字への変換有無)を指定します。初期値はtrueです。
この値をfalseにすることで変換されずにファイルとして送信されます。
Ajax:送信されたファイルデータをviews.pyで処理する
Ajaxで送られたJSONデータをviews.pyで受け取る方法を解説していきます。
Ajaxを通して送られてきたリクエストデータ(送信データ)はHttpRequestオブジェクト(request)に格納されています。
このrequestからファイルデータを抽出するには次のように属性FILESを使用します。
FILESは辞書型オブジェクトのようなもので、キーはinputタグのnameに対応しています。
def ajax_file_send(request):
print("OK")
file = request.FILES['uploadfile']
# ここにファイルの処理を記述
d = {
# レスポンスに渡したいデータを記述
}
return JsonResponse(d)
ブラウザからのリクエストを受けたときに生成されるHttpRequestオブジェクトの利用方法については以下記事をご参照ください。
まとめ
本記事「【Django】Ajaxでファイルをサーバーへ送信・受信(views.pyで処理)する方法」はいかがでしたか。
Webアプリケーションにおいてフォームを利用することは多々あります。
そのときにファイルデータをAjaxを通してサーバーに送信し、views.pyでファイルを処理できることは非常に有用です。
ぜひ本記事を通して、ファイルのAjaxによる送信方法をマスターしてください。