LoginSignup
73
81

More than 5 years have passed since last update.

DjangoページでAjaxしてみる

Last updated at Posted at 2014-06-10

JavascriptでPOSTしようとするとDjangoのCSRF対策に引っかかり失敗してしまうことがあるのだが、公式ドキュメントにちゃんと対策が書かれている。
http://docs.djangoproject.jp/en/latest/ref/contrib/csrf.html?highlight=csrf#ajax

なお、使い回せるようにコピペしたものをGithubに上げたので使いたい方はどうぞ。
https://github.com/juniskw/django_tools/blob/master/csrf_token_ajax.js

例:POSTした文字に「!!!」を付けてアラートするアプリ。

surprise.html
<head>
    <script type="text/javascript" src="{{STATIC_URL}}js/jquery-1.11.0.min.js"></script>
    <script type="text/javascript" src="https://raw.githubusercontent.com/juniskw/django_tools/master/csrf_token_ajax.js"></script>
</head>
<body>
    <h1>Let's Surprise!</h1>
    <form id="surprise_fm" action="surprise/" method="post">
        <input id="your_txt" type="text" name="your_txt">
        <input id="surprise_btn" type="submit">
    </form>
</body>
<script>
$(document).ready(function() {
    $('#surprise_fm').submit(function() {  // ボタンクリックでAJAX
        $.ajax({
            'url':$('form#surprise_fm').attr('action'),
            'type':'POST',
            'data':{
                'your_txt':$('#your_txt').val(),
            },
            'dataType':'json',
            'success':function(response){  // 通信が成功したら動く処理で、引数には返ってきたレスポンスが入る
                alert(response.your_surprise_txt);  // レスポンスからデータを取り出してアラート
            },
        });
        return false;
    });
});
</script>
urls.py
#...
url(r'^surprise/', 'views.for_ajax'),
#...
views.py
def for_view(req):    # ビューを表示する関数
    return render(req,'surprise.html')

def for_ajax(req):    # AJAXに答える関数
    import json
    from django.http import HttpResponse,Http404

    if req.method == 'POST':
        txt = req.POST['your_txt']  # POSTデータを取得して
        surprise_txt = txt + "!!!"  # 加工

        response = json.dumps({'your_surprise_txt':surprise_txt,})  # JSON形式に直して・・

        return HttpResponse(response,mimetype="text/javascript")  # 返す。JSONはjavascript扱いなのか・・

    else:
        raise Http404  # GETリクエストを404扱いにしているが、実際は別にしなくてもいいかも

なお、jsを以下のように一部書き変えれば普通に csrf_token をフォームに入れるだけでも問題ない。

$.ajax({
    // ...
    'data':$('form#surprise_fm').serialize(),
    // ...
});

serialize はおそらくform内のinput要素を全て {name:value,...} の形にまとめてくれるメソッドだと思われる。Djangoの csrf_token はタネを明かせば hiddenタイプのinput要素 みたいなので、この方法なら通常のフォーム処理と同様に機能することができるのだろう。

73
81
3

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
73
81