LoginSignup
93
92

More than 5 years have passed since last update.

DjangoにてPythonでajaxしてみる

Last updated at Posted at 2018-06-26

この記事は Django Advent Calendar 2018 12/7の記事です。

この記事は

DjangoにてPythonajaxする方法を書きとめます。

パッと検索すると、PHPでajaxするサンプルはヒットするものの、
Pythonのサンプルがみつからなかった(記事の初稿当時)ので、
調べて、試して、悩んで、書いてみました。

調べながら、整理しながら、書きのこすというスタンスの記事です。

著者のレベル

おしごとで最近使うメイン武器は VC#,LabVIEW,組み込み系C++ など。
コード書く時間が長いけれど、本当の興味は 工学的なしくみ各種

WEBプログラミングは、初心者です。
大量のインプット沼と、高速なトレンド変化の香りがしていたので、
ずっと避けまくってちかづかなかった。。

記事に出てくるスキルを表にすると、下記のよう。

プログラミング言語 レベル
初めてのWEBプログラミング HTMLでmarqueeしたことあります!!!
Python Qiitaの面白記事を読む専門
Django "ドジャンゴ"って読みにくくない?と思ってた
JavaScript なんでそこにもfunction(){って書くんだ・・?って今でも思ってる
BootStrap WEBデザイン界の"味覇"と聞いてる

想定読者

  • Djangoのチュートリアルを終えている
  • Pythonをかじったことがある
  • わからないことは調べてしまえスタンスな人
  • 通りすがりの強レビュワー

github

忘れないうちにコード置いておきますね。
こちら >> ajax_Django

Anacondaインストールして、Django(2.0以上)をインストールすればローカルで実行できます。
python manage.py runserver コマンドを知らなければ、Djangoのチュートリアルへ行きましょう。

サンプルの実行

三カ月後の他人は自分ですからね!!書き残しておきます。

  • インストール
手順 ノート
Anacondaをインストールする すでにPython環境あるひとはそれを使いましょ
Python仮想環境をつくる Anaconda Navigatorでつくれます
Djangoをインストールする pip install Django
  • ローカルでサンプルを実行
手順 ノート
shellをひらく コマンドプロンプト、PowerShell、Git Bash、などなんでもよい
サンプルのmanage.pyがあるフォルダへ移動する
python manage.py runserverする エラー出たらDjangoチュートリアルに戻って、問題の切り分け!
ブラウザで localhost:8000 をひらく

やりたいこと

Djangoチュートリアルでは、下記のように、views.pyがhtmlをrenderして返してくれます。
ただform送るたびに、全画面が更新されるのは、やっぱつれぇわ。。って思いました。


def test_ajax_app(request):
    hoge = "Hello Django!!"

    return render(request, "test_ajax_app/test_ajax_app.html", {
        "hoge": hoge,
    })

なので、form送ったら、更新された部分HTMLだけを返してほしい。
つまりは、ajaxしたいわけですね。

さてコード解説しますね

みるべきコードは、主に下記です。

file 役割
test_ajax_app/views.py formを送信されたら、なにか処理して、HTMLをレンダリングして返します
test_ajax_app/urls.py formからURLとして呼ばれると、処理を渡すpyファイルまでルーティングします

test_ajax_app/test_ajax_app.html

  • 使用するJavaScriptライブラリ
    • jQuery (slimじゃないやつ)が必要です。また、この記事の趣旨としてはBootStrapは不要です。
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <!-- <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>

  • formにかかわる部分
    • action="/test_ajax_app/ajax/"としている。これはurls.pyによってルーティングされる。
    • {% csrf_token %}Djangoでは、これがformタグ内にないと動きません。
    <form name="name_form" action="/test_ajax_app/ajax/" method="POST">
    <!-- <form name="name_form" action="/test_ajax_app/" method="POST"> -->
      {% csrf_token %}
      <input type="text" id="id_input_text" name="name_input_text" value="999.99">
      <input class="btn" type="submit"> 
    </form>

    <span id="id_div_ajax_response">
      AJAX RESPONSE
    </span>

このsubmitボタンを押したら、Pythonでなんらかの処理をして、
このHTML上に部分的なHTMLとして返したいのです。

test_ajax_app/urls.py

前述のformにあったaction="/test_ajax_app/ajax/"をルーティングしている部分です。
/test_ajax_app/みたいなアクセスのときは、views.pytest_ajax_app()を呼びます。
/test_ajax_app/ajax/みたいなアクセスのときは、同じくviews.pytest_ajax_response()を呼びます。

urlpatterns = [
    path("", views.test_ajax_app),
    path("ajax/", views.test_ajax_response),
]

test_ajax_app/test_ajax_app.html (ふたたび)

今度は JavaScript の部分をみていきます。

      $("form").submit( function(event) {
        event.preventDefault();
        var form = $(this);
        $.ajax({
          url: form.prop("action"),
          method: form.prop("method"),
          data: form.serialize(),
          timeout: 10000,
          dataType: "text",
        })
        .done( function(data) {
          alert("done");
          $("#id_div_ajax_response").text(data);
        })
      });
  • formのsubmitイベントをここで処理する
      $("form").submit( function(event) {
  • デフォルトのform操作を一時的に防止する
        event.preventDefault();
  • ajaxの設定
    • url: formタグのactionプロパティをセットします。なので、"/test_ajax_app/ajax/"が格納される
    • method: methodプロパティ、今回は POST ですね
    • data: serialize()は、formタグ内の送信されるデータを AAA&BBB&CCCみたいな感じに結合します。
      • もちろん、form.serialize() + "&" + "DDD" みたいに文字列結合しても一緒に送信できます。
        $.ajax({
          url: form.prop("action"),
          method: form.prop("method"),
          data: form.serialize(),
          timeout: 10000,
          dataType: "text",
        })

test_ajax_app/views.py (ふたたび)

serialize()されて、ajaxで送信されてきたデータは、
下記の request に格納されてます。

def test_ajax_response(request):
    input_text = request.POST.getlist("name_input_text")
    hoge = "Ajax Response: " + input_text[0]

    return HttpResponse(hoge)

name_input_textというnameを持ったinputタグに入力されたデータは、
下記で取り出すことができます。

    input_text = request.POST.getlist("name_input_text")

そして、部分的なHTMLとして返すには、HttpResponse()を使います。

    return HttpResponse(hoge)

test_ajax_app/test_ajax_app.html (さんどめ)

Pythonから返ってきた部分的なHTMLは、
どこに到着するのでしょうか。

      $("form").submit( function(event) {
        event.preventDefault();
        var form = $(this);
        $.ajax({
          url: form.prop("action"),
          method: form.prop("method"),
          data: form.serialize(),
          timeout: 10000,
          dataType: "text",
        })
        .done( function(data) {
          alert("done");
          $("#id_div_ajax_response").text(data);
        })
      });

そうですね。それっぽい箇所ありますね。
下記の data に格納されて返ってきます。

        .done( function(data) {
          alert("done");
          $("#id_div_ajax_response").text(data);
        })

おわりに

図式があったほうがわかりやすそうなのと、参考文献かかなきゃならないですが、
ここまででタイムアップなので、あとで追記します。

こういうしくみをひも解いて行くのは、あとでしくみを作る時にも役立ちますし、
なんといっても楽しいですね!!

93
92
1

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
93
92