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

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

Flask on Heroku(Python3.4.2) その4 データベースを使う

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

今回は、前回まででフォームに入力できるようになったToDoを、
データベースに登録できるようにします。

データベース管理システムは、今回はPostgreSQLを利用します。postgresapp.com
こちらをインストールしたら、bash

export PATH=$PATH:/Applications/Postgres.app/Contents/Versions/9.4/bin

と打ち、PATHを通します。

その後、

createdb todo

bash上で打ち、データベースを作成します。

データベースの作成が完了したら、flaskアプリケーションのコードを変更します。
config.pyに

SQLALCHEMY_DATABASE_URI = 'postgresql://localhost/todo'

と一行追加します。

__init__.pyを、

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

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

from flask_app import views, models

と編集します。
今回はSQLAlchemyをORMとして使用します。

次に、flask_appディレクトリ下にmodels.pyを作成します。

from flask_app import db

class Todo(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False, index=True)
    detail = db.Column(db.String(5000))
    timestamp = db.Column(db.DateTime)

    def __repr__(self):
        return '<Todo %r>' % (self.title)

ORMを利用することで、modelをこのように記述することができます。

views.pyを編集し、データベースを利用するように変更します。

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('/')
def hello_world():
    return "Hello World!"

@app.route('/register', 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('register.html',
                           form=form,
                           todo_list=todo_list)

register関数を変更し、フォームに入力されたデータをデータベースへ登録するようにしました。
また、その後、データベースに登録されているデータを取得し、レンダリングを行うようにしました。

これに合わせて、テンプレートも変更します。
templates/register.htmlを編集します。

<!DOCTYPE html>
<html>
<head lang="en">
    <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 }}<br>
    {{ todo.timestamp }}
    <hr>
{% endfor %}



</body>
</html>

渡されたデータベースのデータを表示するように変更しました。

コードの編集が終わったら、一度プロジェクトディレクトリの中で、次のコードを実行します。

python
from flask_app import db
db.create_all()

これでデータベースにテーブルが作成され、利用準備が整いました。

http://127.0.0.1:5000/register へアクセスすると、
f:id:asiagohan:20150718184649j:plain
フォームが表示されます。

フォームに値を入力し、送信すると、
f:id:asiagohan:20150810124033j:plain
送信した値がデータベースに保存され、表示されます。

今回のコードは、
asiagohan/flask_tutorial_todo · GitHub
こちらに公開されています。