LoginSignup
14
21

More than 3 years have passed since last update.

Pythonで簡単な掲示板を作成する。(FlaskとSQLを使ったWebアプリ開発入門)#2

Last updated at Posted at 2019-01-22

pythonでスレッド付きの掲示板を作る(リレーショナルデータベース)

前回の続きです。

前回は一つの画面で文章を随時追加していく設計でした。
今回はスレッドを立ててスレッドごとに表示をする掲示板を作成します。

実装環境

  • Window10 Home 64bit
  • Python 3.6.4 |Anaconda, Inc.

ライブラリ

Flask==1.0.2
Flask-SQLAlchemy==2.3.2
Jinja2==2.10
SQLAlchemy==1.2.15
sqlite3(恐らく標準)

データベースについて

データベースではは表形式で管理されるデータを扱います。ここで作る掲示板はスレッドごとに管理をするのでリレーショナルデータベースを用います。構成は以下のようにします。

投稿文書と名前を管理するテーブル

id 日付 名前 文章 スレッドID
1 date1 name1 text1 thread_id1
2 date2 name2 text2 thread_id2

スレッドを管理するテーブル

id スレッド名
1 thread_name1
2 thread_name2

使用するデータベース

ここではPythonで簡単に扱えるSqlite3を使います。

Flask-SQLAlchemy

公式チュートリアルを参考にします。

SQLAlchemyではデータベースの操作をオブジェクト指向のように扱います

app.py
class Article(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    pub_date = db.Column(db.DateTime, nullable=False,
                                default=datetime.utcnow)
    name = db.Column(db.String(80))
    article = db.Column(db.Text())
    thread_id = db.Column(db.Integer, db.ForeignKey('thread.id'), nullable=False)

    def __init__(self, pub_date, name, article, thread_id):
        self.pub_date = pub_date
        self.name = name
        self.article = article
        self.thread_id = thread_id

class Thread(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    threadname = db.Column(db.String(80))
    articles = db.relationship('Article', backref='thread', lazy=True)

    def __init__(self, threadname, articles=[]):
        self.threadname = threadname
        self.articles = articles

def __init__()に関しては追加しないとデータベースを作る際になぜかエラーが出るのでここでは記述してます。
db.relationship()やdb.ForeignKey()を使うことで関連付けをします。

pythonのterminalで以下のようなコマンドを実行するとデータベースが作成されます。

>>> from app import db
>>> db.create_all()
>>>

実装してみる

html部分は面倒なので端折ります。こちらにソースがあります。
flaskとデータベースの設定に関しては前回と同じようにして、あとはスレッドごとに表示する機能を付けると以下のようなプログラムになります。

app.py
@app.route("/")
def main():
    threads = Thread.query.all()
    return render_template("index.html", threads=threads)

@app.route("/thread", methods=["POST"])
def thread():
    thread_get = request.form["thread"]
    threads = Thread.query.all()
    thread_list = []
    threads = Thread.query.all()
    for th in threads:
        thread_list.append(th.threadname)
    if thread_get in thread_list:
        thread = Thread.query.filter_by(threadname=thread_get).first()
        articles = Article.query.filter_by(thread_id=thread.id).all()
        return render_template("thread.html",
                                articles=articles,
                                thread=thread_get)
    else:
        thread_new = Thread(thread_get)
        db.session.add(thread_new)
        db.session.commit()
        articles = Article.query.filter_by(thread_id=thread_new.id).all()
        return render_template("thread.html",
                                articles=articles,
                                thread=thread_get)

@app.route("/result", methods=["POST"])
def result():
    date = datetime.now()
    article = request.form["article"]
    name = request.form["name"]
    thread = request.form["thread"]
    thread = Thread.query.filter_by(threadname=thread).first()
    admin = Article(pub_date=date, name=name, article=article, thread_id=thread.id)
    db.session.add(admin)
    db.session.commit()
    return render_template("bbs_result.html", article=article, name=name, now=date)

if __name__ == "__main__":
    app.run(debug=True)

これで掲示板と同じような動きをするwebアプリの完成です。
HerokuでデプロイしたものにこちらのURLからアクセスできます。
https://bbsapp1.herokuapp.com/

リレーショナルデータベースとのたまっていますがこの記述方法はあまりスマートな気がしないのでもっと簡潔に書ける方法を知っている方は是非ご教授ください。

次回はHerokuでデプロイする方法について解説します。
Herokuでデプロイ

14
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
21