Django
前回、新しいWebアプリ「一次関数表示アプリ」を作成する準備をしました。
今回は一次関数表示アプリのプログラムを解説していきましょう。
今回、いじるファイルは「/webapp/linearfunction/templates/linearfunction/index.html」、「/webapp/linearfunction/views.py」、「/webapp/linearhunction/forms.py」の三つです。
forms.pyは自動では作られていないので、作成しましょう。
webapp
├── bmiapp
│ └── ...
├── db.sqlite3
├── index.cgi
├── linearfunction
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── templates
│ │ └── linearfunction
│ │ └── index.html <- 修正
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ ├── forms.py <- 新規作成
│ └── views.py <- 修正
├── manage.py
├── static
│ ├── 3pysci_logo.png
│ └── favicon.png
└── webapp
├── __init__.py
├── asgi.py
├── definitions.py
├── params.json
├── settings.py
├── urls.py
└── wsgi.py
まずは froms.pyから解説していきます。
/webapp/linerfunction/forms.py
一次関数表示アプリで使用するフォームを設定していきます。
一次関数というと \(y=ax+b\) で表される関数で、xの値に連動して、yの値が変化します。
もちろんその逆、つまりyの値に連動して、xの値も変化するとも言えます。
その際に、どうやって変化するかと決めているのが、aとbの値です。
今回作りたいアプリとしては、aとbの値を入力したら、xとyがどんな変化をするのかをグラフとして表示するアプリです。
ということで最低限「a」、「b」を入力するフォームは必要です。
またグラフを表示するxの範囲、yの範囲を決める必要があります。
ということでxの最大値、最小値、yの最大値、最小値を入力するフォームを作成します。
from django import forms
class LFForm(forms.Form):
a = forms.IntegerField(label='a')
b = forms.IntegerField(label='b')
xmax = forms.IntegerField(label='xmax')
xmin = forms.IntegerField(label='xmin')
ymax = forms.IntegerField(label='ymax')
ymin = forms.IntegerField(label='ymin')
ここで重要な点が一つ。
今回のプログラムでは初期値を決め、ページにアクセスがあった場合にその初期値に合わせてグラフを出力します。
フォームに埋め込む初期値はこのforms.pyでも以下のようにすることで設定することができます。
a = forms.IntegerField(label='a', initial=2)
ただ今回、その初期値自体をグラフを表示させるために使いたかったのですが、どうしても初期値を取得することができませんでした。
そこで行なったのが、forms.pyに初期値を書き込まず、実際に計算を行うファイルであるviews.pyに記入するという方法です。
ということで先ほどのようにforms.pyには初期値が書かれていない状態となっています。
/webapp/linearfunction/views.py
ということでviews.pyでフォームに初期値を設定する方法を解説していきますが、とりあえずはフォームに関係するとこだけにしておきます。
from django.shortcuts import render
from django.http import HttpResponse
from .forms import LFForm
from matplotlib import pyplot as plt
import sys
sys.path.append('../')
from webapp import definitions
def index(request):
params = definitions.readjson()
initial_val = {
'a':1,
'b':0,
'xmin':-10,
'xmax':10,
'ymin':-10,
"ymax":10,
}
params['forms']= LFForm(request.POST or None, initial=initial_val)
if (request.method == 'POST'):
a = int(request.POST['a'])
b = int(request.POST['b'])
xmax = int(request.POST['xmax'])
xmin = int(request.POST['xmin'])
ymax = int(request.POST['ymax'])
ymin = int(request.POST['ymin'])
params['forms'] = LFForm(request.POST)
return render(request, 'linearfunction/index.html', params)
まずインポートで忘れていけないのが、先ほど作成したforms.pyのインポートです。
from .forms import LFForm
次にフォームの初期値を設定します。
def index(request):
params = definitions.readjson()
initial_val = {
'a':1,
'b':0,
'xmin':-10,
'xmax':10,
'ymin':-10,
"ymax":10,
}
params['forms']= LFForm(request.POST or None, initial=initial_val)
「initial_val」に辞書形式で先ほど作成したフォーム(a、b、xmin、xmax、ymin、ymax)名をキーにして、値を定義しています。
これらの数値がそれぞれのフォームの初期値になります。
そして次の1文でフォームの初期値として設定しています。
params['forms']= LFForm(request.POST or None, initial=initial_val)
この後に続いているのが、値が入力された時の動作です。
if (request.method == 'POST'):
a = int(request.POST['a'])
b = int(request.POST['b'])
xmax = int(request.POST['xmax'])
xmin = int(request.POST['xmin'])
ymax = int(request.POST['ymax'])
ymin = int(request.POST['ymin'])
params['forms'] = LFForm(request.POST)
ここでは各値をフォームから取得して、再度フォームに表示する値として設定しています。
最後の1文でそれらの値をindex.htmlに受け渡しています。
return render(request, 'linearfunction/index.html', params)
/webapp/linearfunction/templates/linearfunction/index.html
次にindex.htmlを修正していきます。
修正するのはメインの部分だけなので、他は割愛します。
<!-- main -->
<div class="col-sm-9" style="text-align: center; margin:2rem 0rem 2rem 0rem;">
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
<table style="margin-left:auto; margin-right:auto;">
<tr><td style="text-align: right;">{{ forms.a.label}}:</td><td>{{ forms.a }}</td><td style="text-align: right;">{{ forms.b.label }}:</td><td>{{ forms.b }}</td></tr>
<tr><td style="text-align: right;">{{ forms.xmax.label }}:</td><td>{{ forms.xmax }}</td><td style="text-align: right;">{{ forms.xmin.label }}:</td><td>{{ forms.xmin }}</td></tr>
<tr><td style="text-align: right;">{{ forms.ymax.label }}:</td><td>{{ forms.ymax }}</td><td style="text-align: right;">{{ forms.ymin.label }}:</td><td>{{ forms.ymin }}</td></tr>
<tr><td></td><td></td><td></td><td style="text-align: right;"><input type='submit' value="click"></td></tr>
</table>
</form>
</div>
<!-- /main -->
まず「<form action=”{% url ‘index’ %}” method=”post”>」でこのフォームに値が入力され、Post(送信)されたときには、index.htmlに書かれたコードを実行するように書かれています。
「{% csrf_token %}」はボット対策。
「<input type=’submit’ value=”click”>」はボタンがクリックされたときに値を送信するというボタンのコマンドです。
フォームの配置に関しては、テーブルを使って整列させています。
各フォームのラベルの配置は「{{ forms.フォーム名.label }}」で、フォームを配置は「{{ fomrs.フォーム名 }}」で配置できます。
このようなフォームの配置に関してはこちらの記事で詳しく解説していますので、よかったらどうぞ。
これでフォームに関しては設定できました。
サーバーを起動し、確認してみましょう。
確かに初期値が入力された状態でフォームを配置できました。
次回はグラフを表示する部分を作成していきましょう。
ではでは今回はこんな感じで。
コメント