Django
前回、PythonのWebフレームワークDjangoでとりあえず1ページのWebアプリケーションを作ってみました。
ただ「Webアプリを作った」とはいえ、単に文字が書かれたページを表示しただけ。
今回は前回作ったWebアプリケーションを足し算ができるように改変していきましょう。
そのためには次の順番でプログラムが動くことが必要になります。
- Webページに数字を入力するフォームを作成する
- フォームから入力された値を取得する
- 入力された値を足し算して答えを得る
- 得られた答えを表示する
それでは始めていきましょう。
ちなみに今回は前回のように一つ一つのファイルの画面は出しません。
ファイルやフォルダの位置は「testapp > calcplus > views.py」のように書きますので、ご了承ください。
あとそれぞれの項目に修正するファイル名を記載しておきますので、そちらも参考にしてください。
フォームの作成手順
フォームの作成は以下の手順を行います。
- どのようなフォームがあるかを記載(forms.py)
- フォームの動作を記載(views.py)
- フォームを配置(index.html)
前回もviews.pyやindex.html、urls.pyなど使用しましたが、詳しい解説はしませんでした。
その解説は一度Webアプリケーションを作ってからの方が分かりやすいと思いますので、次回、解説することにしましょう。
ということで今回は動くWebアプリケーションを作ることに集中します。
forms.py(新規)
最初にどのようなフォームを使うか記載するファイルを作成します。
このファイルは最初は存在していないので、以下の場所に「forms.py」を作成します。
場所:/testapp/calcplus/forms.py
そしてその中にこちらのプログラムを記載します。
from django import forms
class CalcPlusForm(forms.Form):
val1 = forms.IntegerField()
val2 = forms.IntegerField()
最初はインポート文でDjango内のformsというフォームのためのライブラリを読み込んでいます。
次に「class CalcPlusForm(forms.Form)」ですが、この後他のファイルからフォームを呼び出すためにこの下に記載するフォーム全体に名前をつけていると考えてください。
そしてフォーム本体が以下の2行。
val1 = forms.IntegerField()
val2 = forms.IntegerField()
一つ目の数字を入れる「val1」というフォームと二つ目の数字を入れる「val2」というフォームを作成しています。
ここで書かれている「forms.IntegerField()」は数字を扱う専用のフォームのことで、他にも文字を扱う専用のフォームやメールアドレスを扱う専用のフォームなどもあります。
それらはまたそのうちに解説したいと思います。
とりあえずこれで使うフォームをDjangoに伝えることができました。
views.py
次にフォームから値を取得し、足し算する、つまりフォームの動作をプログラミングしていきます。
ここでは前回使った「views.py」を修正していきます。
場所:/testapp/calcplus/views.py
前回の「views.py」はこんな感じでした。
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
params = {
'title':'CalcPlus'
}
return render(request, 'calcplus/index1.html', params)
それをこんな感じに修正していきます。
from django.shortcuts import render
from django.http import HttpResponse
from .forms import CalcPlusForm
def index(request):
params = {
'title':'CalcPlus',
'forms': CalcPlusForm(),
'answer':'Answer is '
}
if (request.method == 'POST'):
params['answer'] = 'Answer is ' + str(int(request.POST['val1']) + int(request.POST['val2']))
params['forms'] = CalcPlusForm(request.POST)
return render(request, 'calcplus/index.html', params)
変更した部分を一つずつ解説していきます。
インポート文
「from .forms import CalcPlusForm」を追加しました。
この際「.forms」は同じフォルダ内にある「forms.py」というファイル、つまり先ほど作成したファイルを指しています。
そしてその中にあるCalcPlusFormをインポートしているということです。
params
パラメータを記載している「params」では、「’forms’: CalcPlusForm(),」と「’answer’:’Answer is ‘」が追加されています。
まだ私も詳しく分かっているわけではないのですが、この「params」を作成しておいて、一番最後の文「return render(request, ‘calcplus/index.html’, params)」で記載することで、「params」に書かれているパラメータを全部、「index.html」に渡すことができるようです。
そして「’forms’: CalcPlusForm(),」で先ほど作成した2つのフォームに「forms」という名前を、答えの表示文に「answer」という名前を付けています。
if (request.method == ‘POST’):
「if (request.method == ‘POST’):」のブロックには値が送信された(入力されたではない)時の動作が記述されています。
そしてまずはこちらの文。
params['answer'] = 'Answer is ' + str(int(request.POST['val1']) + int(request.POST['val2']))
「request.POST[‘val1’]」というのは、「val1」のフォームに入力された値を取得するという意味です。
となると「request.POST[‘val2’]」は同様に「val2」のフォームに入力された値を取得しているわけです。
そして先ほど「forms.py」でIntegerFieldを指定しているので、数字(int型)が取得できるはずなのですが、どうやらstr型が取得されているようなので、まずはint型に変換しています。
さらに計算をした後、今度は「’Answer is ‘」というstr型と結合させるため、足し算した数字をstr型に戻しています。
最後にparams[‘answer’]に格納することで、さきほどparamsで設定した’answer’を書き換えています。
「params[‘forms’] = CalcPlusForm(request.POST)」は「request.POST」が入力された値を取得するという意味なので、CalcPlusFormの入力欄にその値を入力するという意味になります。
最初にparamsでCalcPlusForm()としているため、最初は入力欄は空欄となっています。
もし「params[‘forms’] = CalcPlusForm(request.POST)」を書かないと、値を入力してプログラムを実行した後、再度空欄に戻ってしまいます。
そうではなく、入力された数字を保持する(正確には再度入力して保持しているように見せる)ために「params[‘forms’] = CalcPlusForm(request.POST)」が必要なのです。
return render(request, ‘calcplus/index.html’, params)
最後のこの分はparams値を持って、calcplusのフォルダ内にあるindex.htmlを表示しろという指示です。
index.html
次にブラウザに表示する画面を作っていきます。
こちらは前回使っている「index.html」というファイルです。
場所:/testapp/calcplus/templates/calcplus/index.html
前回はこんな感じ。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
<p>Write code here!</p>
</body>
</html>
今回はこんな感じに修正していきます。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
<p>{{ answer }}</p>
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
{{ forms }}
<input type='submit' value="click">
</form>
</body>
</html>
まず増えたのが「<p>{{ answer }}</p>」。
こちらは「views.pyのparams内のanswer」を示しています。
つまり最初は「’answer’:’Answer is ‘」なので「Answer is 」が表示され、値が送信されると「params[‘answer’] = ‘Answer is ‘ + str(int(request.POST[‘val1’]) + int(request.POST[‘val2’]))」、つまり「Answer is 二つの値を足した数」がここに表示されます。
次の部分で<form></form>で囲まれた部分がフォームに関するところです。
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
{{ forms }}
<input type='submit' value="click">
</form>
正直まだ完全には理解していないですが、最初の行は「indexというページでpost(値が送信される)というフォーム」という記述でしょうか。
そして「{% csrf_token %}」はボット対策の一行(何が行われているかは理解していません)。
「{{ forms }}」が「views.pyのparams内のforms」に書かれた内容を表示する部分。
つまり「CalcPlusForms()」= 「forms.py内のCalcPlusForms()」=「val1、val2のフォーム」が呼び出され表示されます。
最後の「<input type=’submit’ value=”click”>」は送信ボタンで押したら、入力した値が送信されます。
これで足し算アプリの作成は完了です。
ターミナルからtestappのフォルダに移動し、「python3 manage.py runserver」を実行しましょう。
実行してみた
実際に実行してみた画面がこちらです。
10足す2で12がちゃんと計算できています。
ここまでできれば計算アプリ、つまりはBMI計算や学校で習う円の面積や円周の長さなどなど作成することができるようになります。
色々作れるようになるってなかなか楽しいものですね!
次回は次次回に前回、今回とやったDjangoに関してファイル間の関係性を解説したいので、そのためのプログラムをインストールしていこうと思います。
ではでは今回はこんな感じで。
コメント