flask(pythonのWebフレームワーク)で、CRUDまで作ってみた。
1 2 |
# まずはフレームワークそのものをインストール pip install flask |
1, お約束のhello,worldから
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# FlaskライブラリのFlaskクラスをインポート from flask import Flask # Flaskアプリケーションのインスタンスを作成(アプリの本体) app = Flask(__name__) # ルーティングを設定。「/」にアクセスがあったときに実行する関数を定義 @app.route("/") def hello(): # ブラウザに表示する文字列を返す(これが画面に表示される内容) return "こんにちは!" # このスクリプトが直接実行されたときだけ、アプリを起動するようにする if __name__ == "__main__": # Flaskアプリケーションを起動(デバッグモード有効、ポート8080で) app.run(debug=True, host="127.0.0.1", port=8080) |
2, いろいろなルーティングを追加してみる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
from flask import Flask app = Flask(__name__) @app.route("/") def home(): return "これはホームページです" @app.route("/about") def about(): return "これはアバウトページです" @app.route("/user/<name>") def user(name): return f"{name}さん、ようこそ!" if __name__ == "__main__": app.run(debug=True, port=8080) |
3, Jinja2テンプレートでHTMLを返す(laravelのbladeみたいなやつ)
templates/ → HTMLテンプレートの検索先
static/ → CSSや画像、JavaScriptなどの静的ファイルの検索先
app.py
1 2 3 4 5 6 7 8 9 10 |
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def home(): return render_template("index.html", title="トップページへようこそ") if __name__ == "__main__": app.run(debug=True,port=8080) |
templates/index.html
1 2 3 4 5 6 7 8 |
<!DOCTYPE html> <html> <head><title>{{ title }}</title></head> <body> <h1>{{ title }}</h1> <p>これはJinja2テンプレートを使ったページです。</p> </body> </html> |
4, テンプレート継承(共通レイアウト)
templates/
├── base.html ← 共通レイアウト
├── index.html ← 中身だけ差し替える子テンプレート
└── about.html ← 別ページの例
共通レイアウト(テンプレート)に、変数的に記述して、それぞれの子テンプレートで値を代入する(なかったらデフォルトの値)
{% block content %}{% endblock %}
base.html(共通レイアウト)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html> <html> <head> <title>{% block title %}Flaskアプリ{% endblock %}</title> </head> <body> <header><h1>共通ヘッダー</h1></header> <main> {% block content %}{% endblock %} </main> <footer><p>共通フッター</p></footer> </body> </html> |
index.html(子テンプレート)
1 2 3 4 5 6 7 |
{% extends "base.html" %} {% block title %}ホームページ{% endblock %} {% block content %} <p>これはホームページのコンテンツです。</p> {% endblock %} |
about.html(別の子テンプレート)
1 2 3 4 5 6 7 |
{% extends "base.html" %} {% block title %}アバウト{% endblock %} {% block content %} <p>これはアバウトページです。</p> {% endblock %} |
app.py(ルーティング追加)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def index(): return render_template("index.html") @app.route("/about") def about(): return render_template("about.html") if __name__ == "__main__": app.run(debug=True) |
5, フォーム送信とPOSTデータの受け取り
app.py(Flaskアプリ本体)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from flask import Flask, request, render_template # Flaskアプリのインスタンスを作成 app = Flask(__name__) # フォーム入力画面のルート @app.route("/") def form(): return render_template("form.html") # フォームを表示 # フォーム送信後の処理(POSTを受け取る) @app.route("/submit", methods=["POST"]) def submit(): name = request.form["name"] # name属性の値を取得(POSTされた値) return render_template("result.html", name=name) # 結果をテンプレートで表示 # アプリの起動設定 if __name__ == "__main__": app.run(debug=True) |
form.html(入力画面)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>フォーム入力</title> </head> <body> <h1>名前を入力してください</h1> <form action="/submit" method="POST"> <input type="text" name="name" required> <input type="submit" value="送信"> </form> </body> </html> |
result.html(結果表示画面)
1 2 3 4 5 6 7 8 9 10 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>結果</title> </head> <body> <h1>ようこそ、{{ name }}さん!</h1> </body> </html> |
6, データベース(SQLite)に保存(SQLAlchemy)して、ユーザ情報をCRUDしてみる(新規追加・更新・削除)
SQLAlchemyをインストール
1 |
pip install flask flask_sqlalchemy |
app.py(Flaskアプリ本体)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
from flask import Flask, render_template, request, redirect, url_for from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # SQLiteデータベース設定 app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///users.db" app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db = SQLAlchemy(app) # Userモデル定義 class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) # ユーザー一覧表示 @app.route("/users") def users(): all_users = User.query.all() return render_template("users.html", users=all_users) # 新規登録フォームの表示 @app.route("/") def form(): return render_template("form.html") # 新規ユーザー登録処理 @app.route("/submit", methods=["POST"]) def submit(): name = request.form["name"] email = request.form["email"] new_user = User(name=name, email=email) db.session.add(new_user) db.session.commit() return redirect(url_for("users")) # 編集フォームの表示 @app.route("/edit/<int:id>") def edit(id): user = User.query.get_or_404(id) return render_template("edit.html", user=user) # 更新処理 @app.route("/update/<int:id>", methods=["POST"]) def update(id): user = User.query.get_or_404(id) user.name = request.form["name"] user.email = request.form["email"] db.session.commit() return redirect(url_for("users")) # ユーザー削除処理 @app.route("/delete/<int:id>") def delete(id): user = User.query.get_or_404(id) db.session.delete(user) db.session.commit() return redirect(url_for("users")) # アプリ起動(初回はDB作成) if __name__ == "__main__": with app.app_context(): db.create_all() app.run(debug=True, port=8080) |
templates/form.html(新規登録)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!DOCTYPE html> <html> <head><title>新規登録</title></head> <body> <h1>ユーザー登録フォーム</h1> <form method="POST" action="/submit"> <input type="text" name="name" placeholder="名前" required><br> <input type="email" name="email" placeholder="メールアドレス" required><br> <input type="submit" value="登録"> </form> <p><a href="/users">ユーザー一覧を見る</a></p> </body> </html> |
templates/users.html(一覧表示)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!DOCTYPE html> <html> <head><title>ユーザー一覧</title></head> <body> <h1>ユーザー一覧</h1> <ul> {% for user in users %} <li> {{ user.name }} - {{ user.email }} [<a href="{{ url_for('edit', id=user.id) }}">編集</a>] [<a href="{{ url_for('delete', id=user.id) }}" onclick="return confirm('削除しますか?');">削除</a>] </li> {% endfor %} </ul> <p><a href="/">新規登録へ戻る</a></p> </body> </html> |
templates/edit.html(編集フォーム)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!DOCTYPE html> <html> <head><title>編集フォーム</title></head> <body> <h1>ユーザー情報の編集</h1> <form method="POST" action="/update/{{ user.id }}"> <input type="text" name="name" value="{{ user.name }}" required><br> <input type="email" name="email" value="{{ user.email }}" required><br> <input type="submit" value="更新"> </form> <p><a href="/users">一覧に戻る</a></p> </body> </html> |