FlaskでHello, world

作成: 2019年02月25日

更新: 2019年02月25日

目標

Pythonがインストールされてるだけの状態からFlaskを使ってテキストフィールドにテキストを打ち込んで打ち込まれたテキストを保存し、表示することができるWebアプリを作る。筆者はWindowsで作成したがたぶんMacでもできます。

環境構築

Pythonのインストールについては特にここには書きません。筆者はanacondaでインストールしたのでanacondaをおすすめします。
まずpipでFlaskをインストールします。

pip install Flask

データベースを使用するためのFlask-SQLAlchemyLをインストールします。

pip install Flask-SQLAlchemy

これで環境構築は終了です。簡単ですね。

プロジェクトの作成

好きな場所にFlaskというディレクトリ(名前は適当)を作り中に以下のようなディレクトリ、ファイルを作成します。
Flask/
 ├ hello.py
 └ templates/
  └ layout.html
  └ hello.html

ファイル名は適当でもいいですが、templatesディレクトリの名前は変えるとエラーが出ます。筆者はタイポして悩みました。
templates/layout.htmlには他のhtmlファイルで使いまわすテンプレートを書きます。今はシンプルでいいのでこんな感じです。

layout.html<!doctype html>
<html>
<head>
<title>{{ title }}</title>
<body>
{% block content %}
<!-- ここにメインコンテンツを書く -->
{% endblock %}
</body>
</head>

template/hello.htmlはこのテンプレートを利用して以下のように書きます。

hello.html{% extends "layout.html" %}
{% block content %}
<h3>Hello</h3>
こんにちは。{{ name }}さん。
<form action="/create" method="POST">
    <input type="text" name="textname" id="textid">
    <input type="submit" value="送信">
</form>
<div class="text">
    {% for text in list %}
      <li>{{ text.text }}</li>
    {% endfor %}
</div>
{% endblock %}

{% %}の部分はflask由来のforやifなどの機能を使いたいときに{{}}の部分はpython側で作った変数を入れたいときに使う。
これらがいわゆるviewの部分です。
次にmodelとcontrollerを組み合わせたhello.pyはこんな感じです。

hello.pyfrom flask import Flask, jsonify, request, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///hello.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)

class Model(db.Model):
    __tablename__ = "books"
    id = db.Column(db.Integer, primary_key=True)
    text = db.Column(db.String(80))

    #初期化
    def __init__(self, text):
        self.text = text


@app.route('/')
def hello():
    name = "Hoge"
    db.session.commit()
    list = Model.query.all()
    #return name
    return render_template('hello.html', title='flask test', name=name, list=list)

@app.route('/create', methods=['post'])
def create():
    name = "Hoge"
    text = request.form["textname"]
    print(text)
    model = Model(text=text)
    print(model.text)
    db.session.add(model)
    db.session.commit()
    list = Model.query.all()
    return render_template('hello.html', title='flask test', name=name, list=list)

if __name__ == "__main__":
    #db.drop_all()  //プログラム終了時にデータベースをリセットしたければここのコメントを外す
    db.create_all()
    app.run(debug=True)

最初に

app=Flask(__name__)

でFlaskの全体を作る。
次の

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///hello.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)

はデータベースの設定です。
その次の

class Model(db.Model):
    __tablename__ = "books"
    id = db.Column(db.Integer, primary_key=True)
    text = db.Column(db.String(80))

    #初期化
    def __init__(self, text):
        self.text = text

でモデルを定義

次の

@app.route('/')
def hello():
    name = "Hoge"
    db.session.commit()
    list = Model.query.all()
    #return name
    return render_template('hello.html', title='flask test', name=name, list=list)

@app.route('/create', methods=['post'])
def create():
    name = "Hoge"
    text = request.form["textname"]
    print(text)
    model = Model(text=text)
    print(model.text)
    db.session.add(model)
    db.session.commit()
    list = Model.query.all()
    return render_template('hello.html', title='flask test', name=name, list=list)

はコントローラーで各URLでの動作の定義をしている。ページはhello.htmlのみで入力フォームに文字を入力して送信するとモデルとしてデータベースに保存。そしてhello.htmlはデータベース内のすべてのモデルを読み取りmodelが持つtextをすべて出力する。
最後のこの部分

if __name__ == "__main__":
    #db.drop_all()  //プログラム終了時にデータベースをリセットしたければここのコメントを外す
    db.create_all()
    app.run(debug=True)

はdb.drop_all()でデータベースを削除できるのでプログラム起動時にデータベースをリセットしたい場合は記述する。db.create_all()でデータベースを作成し、最後にapp.run(debug=True)でFlaskを起動している。
完成したページはこんな感じ
page.png
「Hello, Flask!」と入力すると以下のようになる。
hello.png
ちゃんとデータベースに保存されている。

まとめ

環境構築が楽でディレクトリ構造もシンプルで分かりやすいのが利点。欠点としてはとにかく情報が少ない(特にデータベース関連)。googleさんに聞いてもパッと出てこないのは結構つらい。

参考にしたサイト

Flaskの簡単な使い方
Flask
【Python】FlaskでAPIをさくっとつくる