# 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.Integer
、db.Text()
など受け取るデータの型を定義しています。
db_uri = 'sqlite:///test.db'
app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
db = SQLAlchemy(app)