概要
htmlファイル内で簡単な処理を行った後、formを経由してviews側に情報を返す方法に3日ほど詰まったので、備忘録代わりに書き残しておきます。
参考サイト様
- How to properly append django csrf_token to form in inline javascript?
- 【Django】 csrf_tokenの仕組みとCSRF無効化・画面カスタマイズする方法
手法
formタグを利用した取得が基本となり、ここは公式のチュートリアルにも記載があります。(参照: はじめての Django アプリ作成、その 4)
ただ、単純にJavaScriptでform要素を追加してsubmitしようとすると、「csrf_tokenないよ」みたいなエラーを吐きます。そこで、csrf_tokenを手動で追加する必要があります。以下サンプルです。
htmlファイル
<!--関数起動用のボタン-->
<input type="button" value="集計" onclick="aggregate()">
function aggregate() {
//form作成、メソッドとリンク先の追加
let form = document.createElement('form');
form.method = "POST";
form.action = "{% url 'myapp:feedback' %}";
form.id = "aggregated-form";
//送信したい情報を格納したinput要素作成、type,valueの追加など
let input_container = document.createElement('input');
input_container.type = 'hidden'; //入力フォームの非表示
input_container.name = 'aggregated-information';
//何かしらの処理を施した情報
let information_to_post = .....
//情報の追加
input_container.value = information_to_post;
//csrf_tokenの追加手動
let csrf_element = document.createElement('input');
csrf_element.type = 'hidden';
csrf_element.name = 'csrfmiddlewaretoken';
csrf_element.value = '{{ csrf_token }}';
//csrf_tokenと送信したい情報の追加
form.appendChild(csrf_element);
form.appendChild(input_container);
//文書への追加
document.body.appendChild(form);
//送信
form.submit();
}
あとはurls.pyでfeedbackとviews.pyの紐付けを行い、返ってきた情報をrequest.POSTで取得すれば利用できます。
まとめ
csrf_tokenの正体がinput要素であると知ることができました。JSONとして受け取るなどの工夫を行えばもっと使い勝手が良さそうです。集合知に感謝。