検索
連載

VS CodeとFlaskで作成するToDoリストアプリVisual Studio Codeで始めるPythonプログラミング(2/3 ページ)

簡単なToDoリストアプリを作成しながら、前回は取り上げなかったFlask(やJinja2)のさまざまな機能について見ていく。

Share
Tweet
LINE
Hatena

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>

Webページの表示に使用するテンプレート(showtodo.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 %}

todolistが空リストの場合

 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>

ToDo項目を登録するフォーム

 ここではサブミットにボタンを使わずに<a>要素を使っているが、それ以外はごく普通のHTMLだ。2つの<a>要素はclass属性として「button」を指定し、これを利用して同じスタイルを持った「ボタン的な表示」とする。

 この状態で、launch.jsonファイルを作成して、[Python: Flask]デバッグ構成を選択して、デバッグ実行を行うと次のような表示となる(この手順については前回を参照のこと)。

スタイルシートなしで実行したところ
スタイルシートなしで実行したところ

 画面下部にリンクが表示されていることが分かる。次に、これをボタン風の表示にしてみよう。

CSSの作成:静的ファイルの利用

 Flaskでは、静的ファイル(スタイルシートなど)は「static」フォルダに配置しておくのが一般的だ。そこでこのフォルダを作成して、ここにsytles.cssファイルを配置しておこう。

staticフォルダにstyles.cssファイルを作成
staticフォルダにstyles.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;
}

2つの<a>要素のスタイルを指定
これは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.

ページトップに戻る