Python用のWebフレームワークであるBottleと、O/Rマッパーのpeeweeを使って、Python Professional Programmingの2章のゲストブックアプリケーションを作ってみた。
試したバージョンは、Python2.7、Python3.3、Bottle0.11.6、peewee2.1.5。
ソースコード
guestbook.py
# coding: utf-8 import os from datetime import datetime import peewee from bottle import route, get, post, request, run from bottle import template, static_file, redirect, html_escape BASE_DIR = os.path.dirname(os.path.abspath(__file__)) DATA_FILE = os.path.join(BASE_DIR, 'guestbook.dat') STATIC_DIR = os.path.join(BASE_DIR, 'static') db = peewee.SqliteDatabase(DATA_FILE) class Greeting(peewee.Model): """投稿データのモデル """ name = peewee.CharField() comment = peewee.TextField() create_at = peewee.DateTimeField() class Meta: database = db def create_table(): """データベースファイルがなければデータベーステーブルを作成します """ if not os.path.exists(DATA_FILE): Greeting.create_table() def save_data(name, comment, create_at): """投稿データを保存します """ Greeting.create(name=name, comment=comment, create_at=create_at) def load_data(): """投稿されたデータを返します """ greeting_list = Greeting.select().order_by(Greeting.create_at.desc()) return greeting_list @get('/') def index(): """トップページ テンプレートを使用してページを表示します """ greeting_list = load_data() return template('index', greeting_list=greeting_list) @post('/post') def post(): """投稿用URL """ name = request.forms.name comment = request.forms.comment create_at = datetime.now() # データを保存します save_data(name, comment, create_at) return redirect('/') @route('/static/<filename:path>') def send_static(filename): """静的ファイルを返します """ return static_file(filename, root=STATIC_DIR) def nl2br(s): """改行文字をbrタグに置き換える関数 """ return html_escape(s).replace('\n', '<br />') def datetime_fmt(dt): """datetimeオブジェクトを見やすい表示にする関数 """ return dt.strftime('%Y/%m/%d %H:%M:%S') if __name__ == '__main__': create_table() run(host='127.0.0.1', port=5000)
index.tpl
Bottleのテンプレート内ではPythonコードを書ける。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title>ゲストブック</title> <link rel="stylesheet" href="/static/main.css" type="text/css" /> </head> <body> <div id="main"> <h1>ゲストブック</h1> <div id="form-area"> <p>書き込みをどうぞ。</p> <form action="/post" method="post"> <table> <tr> <th>名前</th> <td> <input type="text" size="20" name="name" /> </td> </tr> <tr> <th>コメント</th> <td> <textarea rows="5" cols="40" name="comment"></textarea> </td> </tr> </table> <p><button type="submit">送信</button></p> </form> </div> <div id="entries-area"> <h2>これまでの書き込み</h2> % from guestbook import nl2br, datetime_fmt % for greeting in greeting_list: <div class="entry"> <h3>{{ greeting.name }} さんの書き込み({{ datetime_fmt(greeting.create_at) }}):</h3> <p>{{! nl2br(greeting.comment) }}</p> </div> % end </div> </div> </body> </html>
static/main.css
body { margin: 0; padding: 0; color: #000E41; background-color: #004080; } h1 { padding: 0 1em; color: #FFFFFF } #main { padding: 0; } #form-area { padding: 0.5em 2em; background-color: #78B8F8; } #entries-area { padding: 0.5em 2em; background-color: #FFFFFF; } .entry p { padding: 0.5em 1em; background-color: #DBDBFF; }
ソースコード一式はbitbucketにも置いときました。
tokibito / python-professional-programming / source / 02-guestbook-bottle-peewee — Bitbucket
雑感
BottleはFlaskと似たようなAPIになっていますね。ただ機能面ではWerkzeug、Jinja2の組み合わせのFlaskのほうが使い勝手がいいかも。
peeweeはシンプルにモデルが書けて使いやすいですね。使い込んでないので機能面でいいのかはわからないけども。