# Flaskで掲示板を作る

# フォルダ構成

フォルダ構成は以下のようになります。


/flask/templates/index.html
                 layout.html
                 bbs_result.html
      /test.py

# ライブラリ

Flask==1.0.2 Flask-SQLAlchemy==2.3.2 Jinja2==2.10 SQLAlchemy==1.2.15 sqlite3

# SQLAlchemy

pythonのORMモジュールです。 ORMはSQLをクラスとして扱えるようにしたものです 使用する理由は、

  • SQLインジェクション対策がサポートされる。
  • クラスなので、SQLをオブジェクト指向で書ける。
  • 引数に変数を入れるため、文字列の結合などが必要ないので短く書ける。

導入の注意点は、

  • ちょっとしたSQLを実行する場合は、ORMを使わない方がコード量が短い。
  • 英語の文献が多いので学習コストが必要。
  • 慣れないうちはブラックボックスのコード。

SQLを操作しやすくする便利な奴くらいで覚えておきましょう。

# データベース構造

簡単にこれだけのデータを持たせることにします。

id 日付 名前 文章
1 date1 name1 text1
2 date2 name2 text2

# コード

# test.py

from flask import Flask, request, render_template
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)

db_uri = 'sqlite:///test.db'
app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
db = SQLAlchemy(app)


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.Text())
    article = db.Column(db.Text())


@app.route("/")
def bbs():
    text = Article.query.all()
    return render_template("index.html", lines=text)


@app.route("/result", methods=["POST"])
def result():
    date = datetime.now()
    article = request.form["article"]
    name = request.form["name"]
    admin = Article(pub_date=date, name=name, article=article)
    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)

# layout.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>BBS</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css">
    <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
</head>

<body>
    {% block content %}
    {% endblock %}
</body>
</html>

# index.html

{% extends "layout.html" %}
{% block content %}
<section class="hero is-primary">
    <div class="hero-body">
      <div class="container">
  <h1 class="title"> 掲示板</h1>
  </div>
    </div>
</section>
<div class="container">
<form action="/result" method="post">
<div class="field">
  <label class="label">Name</label>
  <div class="control">
    <input class="input" type="text" placeholder="Text input" name="name">
  </div>
</div>
<div class="field">
  <label class="label">Message</label>
  <div class="control">
    <textarea class="textarea" name="article"></textarea>
  </div>
</div>
<button class="button" type="submit">作る</button>
</form>
</div>


<div class="container">
  <h2>投稿一覧</h2>
<ul>
{% for line in lines: %}
<li>{{line.name}}
{{line.article}}</li>
{% endfor %}
</ul>
{% endblock %}
</div>

# bbs_result.html

{% extends "layout.html" %}
{% block content %}
<h1>書き込みました</h1>
<br>
<p>{{ now }} {{ name }} {{ article }}</p>

<form action="/" method="get">
    <button type="submit">戻る</button>
</form>
{% endblock %}

# データベースを作成

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.Text())
    article = db.Column(db.Text())

ここでデータを定義します。 db.Integerdb.Text()など受け取るデータの型を定義しています。

db_uri = 'sqlite:///test.db'
app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
db = SQLAlchemy(app)