4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

flaskチートシート

Last updated at Posted at 2023-08-15

flaskもよく忘れるのでチートシートを作ってみました

一番基本

app.py
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フォルダに格納すること
app.py
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)
bbb.html
<html><head><meta charset="utf-8"></title></style></head> 
<body>
  <h3>world</h3>
</body></html>

テンプレートにパラメータを渡す

app.py

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)

うけとった引数を表示するには {{引数}} のように書く

ccc.html
<html><head><meta charset="utf-8"></title></style></head> 
<body>
  <h3>world{{x}}{{y}}</h3>
</body></html>

htmlからformでデータを送信(GET)

app.py
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)

form.html
<!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

form2.html
</head>
<body>
  <h2>{{name}}</h2>
</body>
</html>

htmlからformでデータを送信(POST)

app.py
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"になっている)

formP.html
<!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

form2.html
</head>
<body>
  <h2>{{name}}</h2>
</body>
</html>

テンプレート(jinja)に辞書を渡してキーとバリューを表示

前提 dicに辞書が入っている、pythonからは render_template(aaa.html result=dic)とする

aaa.html
    <ul>
        {% for key, value in results.items() %}
            <li>{{ key }}: {{ value }}</li>
        {% endfor %}
    </ul>

リダイレクト

app.pyの一部
from flask import Flask, redirect, url_for

リダイレクトの実装
以下の例は、/old にアクセスすると /new にリダイレクトされます

app.pyの一部
@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!」という文字列がクライアントに送られます。

これのフローイメージは以下のとおりです
image.png

パスワードの暗号化

Flaskでパスワードを暗号化するために、bcryptというライブラリを使用します

pip install Flask-Bcrypt
app.pyの一部
from flask import Flask
from flask_bcrypt import Bcrypt

app = Flask(__name__)
bcrypt = Bcrypt(app)

パスワードの暗号化

ユーザーから受け取ったパスワード(pw)を暗号化します。

app.pyの一部
hashed_pw = bcrypt.generate_password_hash(pw).decode('utf-8')

パスワードのチェック

ユーザーがログイン時に入力したパスワードと、データベースに保存されているハッシュ化されたパスワードを比較

app.pyの一部
check = bcrypt.check_password_hash(hashed_pw, pw)
if check:
    print("Password is correct!")
else:
    print("Password is incorrect!")

セッション クライアント側にデータを保持する場合

セッションデータをクライアント側に持つのは、あまり良くないとされていますが、デフォルトの場合はこんな使い方になります

app.pyの一部
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ではデフォルトがサーバー側)。というわけでサーバー側に保持する場合のやり方です。

app.pyの一部
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)

このあとは普通に

app.pyの一部
var = session.get('result')   #キーがない可能性がある場合
session["result"] = var       #キーが存在する場合

↑書き込みの場合

app.pyの一部
var = session["result"]

↑読み込みの場合(キーの存在を気にせず直接書き込めます)

flash()関数

シンプルなようで意外とわかりにくいのがflash()関数。chatGPTに聞くと
以下のように返ってきます

Flaskのflash()関数は、ユーザーへの一時的なメッセージを提供するために使用されます。これは、例えばフォームのバリデーションエラーや操作の成功・失敗の通知など、一時的なフィードバックが必要な場面で役立ちます。flash()関数で生成されたメッセージは、リクエスト間で一時的に保存され、次のリクエストで表示された後に消えます。

私はセッション付きのrender_template()関数と理解しました。
以下サンプルとリクエストレスポンスのフローイメージです

app.py
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)
 index.html
<!DOCTYPE html>
<html>
<head>
    <title>Flash Example</title>
</head>
<body>
    {% for message in get_flashed_messages() %}#ここでセッションから取り出される
        <div>{{ message }}</div>
    {% endfor %}
</body>
</html>

上のコードでのやり取り (リクエストレスポンスのフローイメージ)

image.png

4
8
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
4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?