[[ともっくす alloc] init]

ともっくすの雑多な日記と技術的なメモ

Flaskのチュートリアルをやってみる① 〜環境設定からデータベースまで

Flaskのチュートリアルをやるに当たって参考にしたサイトはこちら.

本家と日本語訳サイトがあるが,日本語訳サイトは本家に比べて古いので若干異なる部分があるうえ,日本語訳されていない部分が多い.

ということで,英語に抵抗がないならもちろん本家で,苦手なら日本語訳サイトを見つつ本家と比べながら進めるのが良いかと.

とりあえず,日本語訳サイトだけを鵜呑みにするのは良くないかもしれない.

完成版.
f:id:o_tomox:20131127184519p:plain

チュートリアルをそのままじゃなくて,ちょっと変えてるので,一応GitHubにあげとこう.
> o-tomox/flaskr · GitHub

内容

このチュートリアルではflaskrというブログアプリケーションを作成する.

すごく簡単にできる.

機能としては以下がある.

  1. 設定したユーザーのみがログイン,ログアウト可能
  2. ログインした状態でのみ新規エントリーを作成可能
  3. すべてのエントリーを表示可能で,新しいエントリーが上に表示

全てチュートリアル通りに記述するわけではないことに注意.

で,チュートリアルは基本的に全て英語だが,以降は日本語で作っていく.

変な日本語があったとしても,それは原文にほぼ忠実だからだと思ってほしい…

環境設定等

まず,Flaskをインストールして,以下のようなフォルダを作成する.

/flaskr
    /static
    /templates

実際には,こんな感じで作成していく.

$ mkvirtualenv env-flasktut
$ pip install Flask
$ mkdir flaskr
$ cd flaskr
$ mkdir static templates

staticフォルダには,CSSやJSファイル,各種画像を置いていき,templatesフォルダには,Jinja2テンプレートファイルを置いていく.

で,次にflaskrで使うデータベースを用意する.

schema.sqlというファイルを作り,以下を記述する.

drop table if exists entries;
create table entries (
  id integer primary key autoincrement,
  title string not null,
  text string not null
);

見たらわかるように,これは各エントリーを格納しておくテーブルで,titleとtextという属性を持つ.

アプリのセットアップ

ここから本体を作成していく.

まず,flaskrフォルダ内にflaskr.pyを作成し,以下を記述する.

# -*- coding: utf-8 -*-

import sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash


# 各種設定
DATABASE = 'flaskr.db' # <- チュートリアルと異なる
DEBUG = True
SECRET_KEY = 'development key'
USERNAME = 'admin'
PASSWORD = 'default'

# アプリ生成
app = Flask(__name__)
app.config.from_object(__name__)
app.config.from_envvar('FLASKR_SETTINGS', silent=True)

# DB接続
def connect_db():
    return sqlite3.connect(app.config['DATABASE'])


if __name__ == '__main__':
    app.run()

app.config.from_object()は,与えられたオブジェクトの内で大文字の変数をすべて取得する.
つまり,各種設定の項目のDATABASEやSECRET_KEYなどがapp.configに登録される.

こんな感じでセットアップは完了.

で,実行すると,http://127.0.0.1:5000/にアクセスできる.

が,404が返ってくる.

なぜなら,Viewが設定されていないから.

データベース

まず,以下のコマンドでデータベースを作成する.

$ sqlite3 flaskr.db < schema.sql

これで,flaskrフォルダ配下にflaskr.dbが作成された.*1

そして,flaskr.pyに以下のfrom-import文とinit_db()を追記する.

from contextlib import closing
def init_db():
    with closing(connect_db()) as db:
        with app.open_resource('schema.sql', mode='r') as f:
            db.cursor().executescript(f.read())
        db.commit()

Pythonシェルからこの関数を実行する.

$ python
>>> from flaskr import init_db
>>> init_db()

これで,データベースの初期化ができる.

さらに,データベース処理の前後で別処理をするために,以下をflaskr.pyに追記する.

@app.before_request
def before_request():
    g.db = connect_db()

@app.teardown_request
def teardown_request(exception):
    db = getattr(g, 'db', None)
    if db is not None:
        db.close()

before_requestでデコレートされた関数は,リクエスト前に呼ばれるので,ここで,データベース接続などを行う.

before_requestと対となるafter_requestがあるが,これは例外が発生した場合に呼ばれる保証がないので,代わりにteardown_requestを使い,ここで,データベースのクローズなどを行う.

gとは,とりあえず何でも格納しておきたいものを格納しておくもので,データベースのコネクションとか,ログインしてるユーザ情報とかを保持しておくのが良い.

*1:この部分はチュートリアルと異なる