flaskもよく忘れるのでチートシートを作ってみました
一番基本
from flask import Flask #Flaskをインポート
app = Flask(__name__) #インスタンス作成
#ルーティングはデコレータがやってくれる
@app.route('/aaa', methods=['GET']) #/aaaにgetメソッドでアクセスされたとき以下実行
def aaa(): #中身の関数
return "<h1>hello</h1>" #helloを太字で出力
if __name__ == "__main__": #いつものやつw
app.run(debug=True) #デバッグオンで動かすと、コード変更時に楽なので
起動方法
サーバー起動 python app.py
ブラウザからは http://127.0.0.1:5000/aaa でアクセス
テンプレートを使う(jinja2)
htmlファイルは必ずtemplatesフォルダに格納すること
from flask import Flask, render_template #新たなメソッドの導入
app = Flask(__name__)
@app.route('/aaa', methods=['GET'])
def aaa():
return render_template("bbb.html") #render_templateでbbb.htmlを呼び出す
if __name__ == "__main__":
app.run(debug=True)
<html><head><meta charset="utf-8"></title></style></head>
<body>
<h3>world</h3>
</body></html>
テンプレートにパラメータを渡す
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/aaa', methods=['GET'])
def aaa():
return render_template("ccc.html",x=" wide",y=" web ")#ここで引数を渡している
if __name__ == "__main__":
app.run(debug=True)
うけとった引数を表示するには {{引数}} のように書く
<html><head><meta charset="utf-8"></title></style></head>
<body>
<h3>world{{x}}{{y}}</h3>
</body></html>
htmlからformでデータを送信(GET)
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET'])#フォームの送信
def index():
return render_template('form.html')
@app.route('/ggg', methods=['GET'])#結果の処理
def index2():
name = request.args.get('name')
return render_template('form2.html', name=name)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
<title>Flask Form GET</title>
</head>
<body>
<form action="/ggg" method="get">
<input type="text" name="name">
<input type="submit" value="Submit">
</form>
</body>
</html>
結果を表示するためのhtml
</head>
<body>
<h2>{{name}}</h2>
</body>
</html>
htmlからformでデータを送信(POST)
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET'])#フォームの送信
def index():
return render_template('formP.html')
#結果の処理部分
@app.route('/ggg', methods=['POST']) #POSTになっている点に注目
def index2():
name = request.form.get('name')
return render_template('form2.html', name=name)
if __name__ == '__main__':
app.run(debug=True)
フォーム(method="post"になっている)
<!DOCTYPE html>
<html>
<head>
<title>Flask Form GET</title>
</head>
<body>
<form action="/ggg" method="post">
<input type="text" name="name">
<input type="submit" value="Submit">
</form>
</body>
</html>
結果表示のためのhtml
</head>
<body>
<h2>{{name}}</h2>
</body>
</html>
テンプレート(jinja)に辞書を渡してキーとバリューを表示
前提 dicに辞書が入っている、pythonからは render_template(aaa.html result=dic)とする
<ul>
{% for key, value in results.items() %}
<li>{{ key }}: {{ value }}</li>
{% endfor %}
</ul>
リダイレクト
from flask import Flask, redirect, url_for
リダイレクトの実装
以下の例は、/old にアクセスすると /new にリダイレクトされます
@app.route('/old')
def old_endpoint():
return redirect(url_for('new_endpoint'))
@app.route('/new')
def new_endpoint():
return "This is the new endpoint!"
リクエスト(/old): クライアントが /old エンドポイントにアクセスを試みます。
リダイレクト命令: サーバーはクライアントに対して、新しいエンドポイント /new にリダイレクトするよう命じます。これは通常、HTTPステータスコード302(一時的リダイレクト)または301(永続的リダイレクト)で行われます。
リクエスト(/new): クライアントはサーバーからのリダイレクト指示に従い、自動的に /new エンドポイントに新たなリクエストを送信します。
レスポンス文字列: /new エンドポイントからの応答として「This is the new endpoint!」という文字列がクライアントに送られます。
パスワードの暗号化
Flaskでパスワードを暗号化するために、bcryptというライブラリを使用します
pip install Flask-Bcrypt
from flask import Flask
from flask_bcrypt import Bcrypt
app = Flask(__name__)
bcrypt = Bcrypt(app)
パスワードの暗号化
ユーザーから受け取ったパスワード(pw)を暗号化します。
hashed_pw = bcrypt.generate_password_hash(pw).decode('utf-8')
パスワードのチェック
ユーザーがログイン時に入力したパスワードと、データベースに保存されているハッシュ化されたパスワードを比較
check = bcrypt.check_password_hash(hashed_pw, pw)
if check:
print("Password is correct!")
else:
print("Password is incorrect!")
セッション クライアント側にデータを保持する場合
セッションデータをクライアント側に持つのは、あまり良くないとされていますが、デフォルトの場合はこんな使い方になります
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'secret_key'# セッションの暗号化に使用される秘密鍵
# セッションから情報を取得する
var = session.get('result')
#または
var = session['result']
キーがセッションに存在するかどうかが不明確な場合、KeyErrorを防ぐために session.get('result') のようなメソッドを使用することが推奨されます。しかし、キーの存在が保証されている場合、直接 session['result'] としてアクセスすることができます。
セッション サーバー側にデータを保持する場合
flaskはセッションデータをデフォルトではクライアント側に保持するのですが、安全性を高めたいときはサーバー側に持つのが良いとされています。(phpやdjangoではデフォルトがサーバー側)。というわけでサーバー側に保持する場合のやり方です。
from flask import Flask, session
from flask_session import Session
app.config['SECRET_KEY'] = 'your_secret_key_here'#秘密鍵
app.config['SESSION_TYPE'] = 'filesystem'#ファイルに保存
Session(app)
このあとは普通に
var = session.get('result') #キーがない可能性がある場合
session["result"] = var #キーが存在する場合
↑書き込みの場合
var = session["result"]
↑読み込みの場合(キーの存在を気にせず直接書き込めます)
flash()関数
シンプルなようで意外とわかりにくいのがflash()関数。chatGPTに聞くと
以下のように返ってきます
Flaskのflash()関数は、ユーザーへの一時的なメッセージを提供するために使用されます。これは、例えばフォームのバリデーションエラーや操作の成功・失敗の通知など、一時的なフィードバックが必要な場面で役立ちます。flash()関数で生成されたメッセージは、リクエスト間で一時的に保存され、次のリクエストで表示された後に消えます。
私はセッション付きのrender_template()関数と理解しました。
以下サンプルとリクエストレスポンスのフローイメージです
from flask import Flask, flash, redirect, url_for, render_template
app = Flask(__name__)
app.secret_key = '!!#$%' # セッションデータを暗号化するためのキー
@app.route('/sample')
def sample():
flash('This is a flash message!')#このメッセージは最終的にindex.htmlに渡されるが一時的にセッションに保存
#time.sleep(1)
return redirect(url_for('index'))
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
<title>Flash Example</title>
</head>
<body>
{% for message in get_flashed_messages() %}#ここでセッションから取り出される
<div>{{ message }}</div>
{% endfor %}
</body>
</html>