この記事は Django Advent Calendar 2018 12/7の記事です。
この記事は
DjangoにてPythonでajaxする方法を書きとめます。
パッと検索すると、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.py
のtest_ajax_app()
を呼びます。
/test_ajax_app/ajax/
みたいなアクセスのときは、同じくviews.py
のtest_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"
みたいに文字列結合しても一緒に送信できます。
- もちろん、
- url: formタグのactionプロパティをセットします。なので、
$.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);
})
おわりに
図式があったほうがわかりやすそうなのと、参考文献かかなきゃならないですが、
ここまででタイムアップなので、あとで追記します。
こういうしくみをひも解いて行くのは、あとでしくみを作る時にも役立ちますし、
なんといっても楽しいですね!!