VS CodeとFlaskで作成するToDoリストアプリ:Visual Studio Codeで始めるPythonプログラミング(2/3 ページ)
簡単なToDoリストアプリを作成しながら、前回は取り上げなかったFlask(やJinja2)のさまざまな機能について見ていく。
Jinja2テンプレート
Webページの表示に利用するJinja2テンプレートは次のようになっている(スタイルシートは使用しないバージョン)。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>To Do List sample app</title>
</head>
<body>
<h1>ToDo List</h1>
{% if not todolist %}
<p>you can register something to do.</p>
{% else %}
<p>your todo list:</p>
{% endif %}
<ul>
{% for item in todolist %}
<li {% if item.done %}style="color: lightgray"{% endif %}>
{{ item.title }}
<a href="/updatedone/{{ item.item_id }}">[done!]</a>
<a href="/deleteitem/{{ item.item_id }}">[delete]</a>
</li>
{% endfor %}
</ul>
<form action="/additem" method="post" name="myform">
<p>
<input type="text" name="title">
</p>
<a href="javascript:document.myform.submit()" class="button">submit</a>
<a href="/deletealldoneitems" class="button">delete all done items</a>
</form>
</body>
</html>
前回はJinja2が提供する構文の中で、「{{ 変数 }}」だけを使用していた。これは「{{ }}」に囲まれた変数の内容をその場所に描画するというものだ。今回はこれに加えて、以下を利用している。
- {% if <条件> %}〜{% else %}〜{% endif %}:条件分岐
- {% for <変数> in <シーケンス> %}〜{% endfor %}:Pythonのシーケンス(リストなど)に含まれる項目をループする
例えば、上のテンプレートではrender_template関数呼び出しで渡されるtodolist変数が空のリストかどうかに応じて、表示するテキストを変更している。
{% if not todolist %}
<p>you can register something to do.</p>
{% else %}
<p>your todo list:</p>
{% endif %}
Pythonでは「空リストはFalseとして扱われる」ことから、上記のように記述できる。また、todolist変数が参照するリストの各要素は次のようにして、反復処理している。
<ul>
{% for item in todolist %}
<li {% if item.done %}style="color: lightgray"{% endif %}>
{{ item.title }}
<a href="/updatedone/{{ item.item_id }}">[done!]</a>
<a href="/deleteitem/{{ item.item_id }}">[delete]</a>
</li>
{% endfor %}
</ul>
「for」に続けて記述した変数(item)を介して、上のテンプレートでは各要素のメンバの値にアクセスしている(item.title、item.item_id、item.done)。また、上のテンプレートでは、{% if %}文を使い、完了した項目については文字色をライトグレーとしている。2つの<a>要素はapp.pyファイルで定義したURL(/updatedoneと/deleteitem)へのリンクとなっている。これらをクリックすることで、それぞれupdate_todoitemdone関数とdelete_todoitem関数が呼び出される。このときには、各ToDo項目が振られているID(item_id)をURLに含めるようにしているので、「/updatedone/0」「/deleteitem/1」のようなURLへのリクエストとなるようにしている。
ToDo項目を登録するフォームは次のようになっている。
<form action="/additem" method="post" name="myform">
<p>
<input type="text" name="title">
</p>
<a href="javascript:document.myform.submit()" class="button">submit</a>
<a href="/deletealldoneitems" class="button">delete all done items</a>
</form>
ここではサブミットにボタンを使わずに<a>要素を使っているが、それ以外はごく普通のHTMLだ。2つの<a>要素はclass属性として「button」を指定し、これを利用して同じスタイルを持った「ボタン的な表示」とする。
この状態で、launch.jsonファイルを作成して、[Python: Flask]デバッグ構成を選択して、デバッグ実行を行うと次のような表示となる(この手順については前回を参照のこと)。
画面下部にリンクが表示されていることが分かる。次に、これをボタン風の表示にしてみよう。
CSSの作成:静的ファイルの利用
Flaskでは、静的ファイル(スタイルシートなど)は「static」フォルダに配置しておくのが一般的だ。そこでこのフォルダを作成して、ここにsytles.cssファイルを配置しておこう。
サンプルなので、ここではstyles.cssファイルの内容は以下だけとする。
.button {
position: relative;
display: inline-block;
padding: 0.25em 0.5em;
text-decoration: none;
color: #FFF;
background: #03A9F4;/*色*/
border: solid 1px #0f9ada;/*線色*/
border-radius: 4px;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.2);
text-shadow: 0 1px 0 rgba(0,0,0,0.2);
}
.button:active {/*押したとき*/
border: solid 1px #03A9F4;
box-shadow: none;
text-shadow: none;
}
これはWeb上でよさげなボタン風デザインを探した結果、「CSSで作る!押したくなるボタンデザイン100(Web用)」からいただいたものだ。
スタイルシートの準備はこれでOKだが、もう1つすることがある。showtodo.htmlテンプレートの<head>要素内に次を追加しておこう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>To Do List sample app</title>
<link rel="stylesheet" type="text/css"
href="{{ url_for('static', filename='styles.css')}}" />
</head>
<body>
<!-- 省略 -->
</body>
</html>
ここではJinja2が提供する「url_for」関数を利用して、スタイルシートのURLを自動生成するようにしている点に注意しよう。
この状態で、デバッグ実行をしてみると、次のようになる。
既に述べた通り、今までに見たコードにはバグが仕込まれているので、最後にデバッグ実行をしながら、バグを修正してみることにしよう。
Copyright© Digital Advantage Corp. All Rights Reserved.