読者です 読者をやめる 読者になる 読者になる

ポーカー、プログラミング、もぐ

ポーカーとプログラミングともぐもぐについてのブログ。

Flask on Heroku(Python3.4.2) その5 カスタムフィルターを使う

プログラミング

asiagohan.hatenablog.com
asiagohan.hatenablog.com
asiagohan.hatenablog.com
asiagohan.hatenablog.com

今回はカスタムフィルターを使い、データの表現方法をよりわかりやすいものにします。

そもそもカスタムフィルターは、Jinja2の機能で、アプリケーションの表示部分(viewの部分)の問題を解決するためのものです。
例えば、
・データベースから取得した日付データを、任意のフォーマットで表示したい
・URLをエンコードして表示したい
などです。

ここでは、
・日付データのフォーマットを変更する
・入力された改行を改行タグ(
)とする
二点についてカスタムフィルターを使います。

まず、これはカスタムフィルターとは関係ありませんが、Hello Worldをいい加減削除し、
"/"へregister関数を紐付けます。
一緒に、register.htmlテンプレートをindex.htmlへリネームします。

import datetime
from flask import render_template, flash, redirect, url_for, request

from flask_app import app, db
from .forms import TodoForm
from .models import Todo

@app.route('/', methods=['GET', 'POST'])
def register():
    form = TodoForm()
    if request.method == 'POST' and form.validate():
        title = form.title.data
        detail = form.detail.data
        timestamp = datetime.datetime.utcnow()
        todo = Todo(title=title, detail=detail, timestamp=timestamp)
        db.session.add(todo)
        db.session.commit()
        return redirect(url_for('register'))

    todo_list = Todo.query.order_by(Todo.timestamp.desc())
    return render_template('index.html',
                           form=form,
                           todo_list=todo_list)

次に、flask_appディレクトリ下にカスタムフィルターファイルを追加します。

datetimeformat.py

from jinja2 import Markup

def datetimeformat(value, format='%Y-%m-%d %H:%M '):
    return Markup(value.strftime(format))

newlinetobr.py

from jinja2 import Markup
from jinja2 import escape

def newlinetobr(value):
    return Markup('<br />'.join(escape(value).splitlines()))

このカスタムフィルターを登録します。
flask_app/__init__.pyを編集します。

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

from .datetimeformat import datetimeformat
from .newlinetobr import newlinetobr

app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)

app.jinja_env.filters['datetimeformat'] = datetimeformat
app.jinja_env.filters['newlinetobr'] = newlinetobr

from flask_app import views, models

登録が終わったら、テンプレートファイルを編集します。
先ほどリネームしたtemplates/index.htmlの、日付データと詳細データ部分を変更します。

<!DOCTYPE html>
<html>
<head lang="ja">
    <meta charset="UTF-8">
    <title>register</title>
</head>
<body>
<h2>REGISTER</h2>
  <form action="" method="post" name="register">
      {{ form.hidden_tag() }}
      <p>
          title:<br>
          {{ form.title() }}<br>
      </p>
      {% for error in form.title.errors %}
            <span style="color: red;">TITLEを入力してください。</span>
          {% endfor %}<br>

      <p>
          detail:<br>
          {{ form.detail() }}<br>
      </p>
      <p><input type="submit" value="投稿" class="btn btn-primary"></p>
  </form>

{% for todo in todo_list %}
    <h2>{{ todo.title }}</h2>
    {{ todo.detail | newlinetobr }}<br>
    {{ todo.timestamp | datetimeformat }}
    <hr>
{% endfor %}



</body>
</html>

カスタムフィルターを利用するとき、
{{ argument | function }}
という形で表記します。

すべての編集が終わった段階で、
http://127.0.0.1:5000/へアクセスすると、

f:id:asiagohan:20150813222912j:plainf:id:asiagohan:20150813222912j:plain
このように、日付と詳細の表示方法が変わっています。

今回のソースコードは、
https://github.com/asiagohan/flask_tutorial_todo/tree/layout

こちらにアップされています。