ビジネスパーソン・ガジェット置場 empty lot for business

営業や仕事、それに伴う生活を便利に楽にするツール、ガジェットを作ります。既にあるツールも自分用にカスタマイズ。

python: Flaskアプリの作成③ Flaskでデータベースに投稿するページを作る

備忘録です。

Flaskでhello worldが表示されるように設計できたら、次はデータベースを使用するページを作成してみます。その備忘録です。

データベース

SQALchemyでデータベースを作成管理する

その1 pip3でSQLAlchemy等をインストール

$ pip3 install Flask-SQLAlchemy
$ pip3 install flask_migrate
$ pip3 install pytz
$ pip3 install datetime

pytz 等も必要になるので入れておきます。

 

pip3 freezeで確認するとSQLAlchemyがインストールされているのが確認できます。

alembic==1.8.1
click==8.1.3
DateTime==4.5
Flask==2.2.1
Flask-Migrate==3.1.0
Flask-SQLAlchemy==2.5.1
greenlet==1.1.2
importlib-metadata==4.12.0
itsdangerous==2.1.2
Jinja2==3.1.2
Mako==1.2.1
MarkupSafe==2.1.1
pytz==2022.1
SQLAlchemy==1.4.39
Werkzeug==2.2.1
zipp==3.8.1
zope.interface==5.4.0

 

その2 SQLAlchemyのインポート

app.pyにインポートします。同時にflask_migrateとdatetime(作成日時などで使用)もインポートしてしまいます。

# app.py

from flask import Flask, render_template, flash, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from datetime import datetime
from datetime import date
import pytz

※2行目からが今回の追加分

 

その3 データベース周りの設定をapp.pyに追記

  • アプリケーション構成ファイルにデータベースを追加
  • データベースのインスタンスを作成し初期化

# app.py

app = Flask(__name__)

# アプリケーション構成ファイルにデータベースを追加
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = "my super secret key that no one is supporsed to know"
# データベースの初期化 db = SQLAlchemy(app) migrate = Migrate(app, db)

 

 

その4 モデルを作成

# やりたいことを登録するモデル
class Aspiration(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255))
    content = db.Column(db.Text)
    status = db.Column(db.Integer)
    created_at = db.Column(db.DateTime, default=datetime.now(pytz.timezone('Asia/Tokyo')))
    completed_at = db.Column(db.DateTime)

 

その5 DBを作成する

python3で対話式モードに移行

from app import db
db.create_all()

 

その6 一覧で表示するページを作る

#app.py

@app.route('/aspirations')
def aspirations():
    aspirations = Aspiration.query.order_by(Aspiration.created_at)
    return render_template('aspirations.html', aspirations=aspirations)

 

# aspirations.html

{% extends "base.html"%}

{% block content %}
<h1>やりたいこと一覧</h1>
{% for aspiration in aspirations %}
  <div class="shadow p-3 mb-5 bg-body rounded">
    <h2>{{ aspiration.title }}</h2>
    {{ aspiration.created_at }}
    {{ aspiration.content }}
  </div>
{% endfor %}
{% endblock %}

 

その7 投稿するためのページを作成

投稿フォームを作成

 1)pip3でflask_wtfをインストール

$ pip3 install flask_wtf

pip3 freezeで確認すると

alembic==1.8.1
click==8.1.3
DateTime==4.5
Flask==2.2.1
Flask-Migrate==3.1.0
Flask-SQLAlchemy==2.5.1
Flask-WTF==1.0.1
greenlet==1.1.2
importlib-metadata==4.12.0
itsdangerous==2.1.2
Jinja2==3.1.2
Mako==1.2.1
MarkupSafe==2.1.1
pytz==2022.1
SQLAlchemy==1.4.39
Werkzeug==2.2.1
WTForms==3.0.1
zipp==3.8.1
zope.interface==5.4.0

※下線部分が必要

 

2)app.pyで各種インポート

# app.py

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField, BooleanField, ValidationError, TextAreaField
from wtforms.validators import DataRequired, EqualTo, Length
from wtforms.widgets import TextArea

 

3)フォームクラスを作成

# app.py

class AspirationForm(FlaskForm):
    title = StringField('Title', validators=[DataRequired()])
    content = StringField('Content', validators=[DataRequired()], widget=TextArea())
    submit = SubmitField('Submit')

 

4)フォーム用のページを作成

# add_aspiration.html

{% extends "base.html"%}

{% block content %}

<h1>やりたいことを投稿</h1>
<br/>
<div class="shadow p-3 mb-5 bg-body rounded">
  <form method="POST">
    {{ form.hidden_tag() }}

    {{ form.title.label(class="form-label") }}
    {{ form.title(class="form-control") }}
    <br/>

    {{ form.content.label(class="form-label") }}
    {{ form.content(class="form-control") }}
    <br/>

    {{ form.submit(class="btn btn-secondary") }}

  </form>

</div>

 

5)app.pyでページを作成

@app.route('/add-aspiration', methods=['GET', 'POST'])
def add_aspiration():
    form = AspirationForm()
     if form.validate_on_submit(): status = 0 aspiration = Aspiration(title=form.title.data, content=form.content.data, status=status) # フォーム内の値をクリアする form.title.data = '' form.content.data = '' # データベースに追加する db.session.add(aspiration) db.session.commit() return render_template('add_aspiration.html', form=form)

 

上記投稿フォームが完成。TitleとContentを入力すると

 

上記のように一覧ページに表示ができました。
あとは、表示内容など好きなように変更したり、navbarに追記してメニューバーでページを選択できるようにすれば完成。

編集ページや、各記事ページは別途記載。