Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
79
Help us understand the problem. What is going on with this article?
@juniskw

DjangoページでAjaxしてみる

More than 5 years have passed since last update.

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要素 みたいなので、この方法なら通常のフォーム処理と同様に機能することができるのだろう。

79
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
juniskw

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
79
Help us understand the problem. What is going on with this article?