1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Django】JavaScriptで動的に作成されたformにcsrf_tokenを追加する

Posted at

概要

htmlファイル内で簡単な処理を行った後、formを経由してviews側に情報を返す方法に3日ほど詰まったので、備忘録代わりに書き残しておきます。

参考サイト様

手法

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として受け取るなどの工夫を行えばもっと使い勝手が良さそうです。集合知に感謝。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?