目次
7. テンプレートをレンダリングする render_template()
0. ウェブの動作原理とフラスコの関係
B/S および C/S アーキテクチャ
- B/S: ブラウザ/サーバー アーキテクチャ (クライアントを更新する必要があります)
- C/S: クライアント/サーバー アーキテクチャ (ページを更新して更新します) (主流になる可能性があります)
ウェブのしくみ
クライアント > サーバー > python (フラスコ) > データベース (mysql)
1.フラスコをインストールする
Flask は Web フレームワークです. Flask は主に 2 つのコア関数ライブラリ, Werkzeug (ビジネス処理を担当) とJinja2 (セキュリティ)を含みます. Flask は簡潔で拡張が容易です.
pip install flask
import flask
print(flask.__version__)
2. 基本的な枠組み
@app.route(rule, options) デコレーターは、関数をトリガーするルート (URL) を Flask に指示します。
rule は、 関数との URL バインディングを示します。
options 基本となる Rule オブジェクトに転送するパラメーターのリスト。
from flask import Flask
app = Flask(__name__) # 创建应用实例
# 视图函数(路由)
@app.route("/")
def hello_world():
return "Hello, World!"
if __name__ == '__main__':
app.run(debug = True) # 启动服务
として保存します app.py
。サービスはデフォルトでポート 5000 を使用して開始され、ブラウザで http://127.0.0.1:5000/ を開くと、Hello World! という単語が表示されます。
app.run(ホスト、ポート、デバッグ、オプション)
3. @app.route('') のルーティング
@app.route('/hello')
def hello_world():
return 'hello world'
4. 可変ルール
URL の一部を関数へのキーワード引数としてマークすることにより、URL に変数を追加できます。 <variable_name>
from flask import Flask
app = Flask(__name__)
@app.route('/hello/<username>')
def hello(username):
return f'Hello {username}!'
if __name__ == '__main__':
app.run(debug = True)
ブラウザにhttp://127.0.0.1:5000/hello/Flaskと入力すると、ブラウザの出力は次のようになります。
こんにちはフラスク!
を使用すると <converter:variable_name>
、必要に応じてコンバーターを追加して、変数の規則を指定できます。
コンバータ | 例証する |
---|---|
string |
(デフォルト) スラッシュを含まない任意のテキスト |
int |
正整数 |
float |
正浮点数 |
path |
比string もう 1 つの関数。スラッシュを含めることができます |
完全な例:
from flask import Flask
from markupsafe import escape
app = Flask(__name__)
@app.route('/hello/<username>')
def hello(username):
return f'Hello {username}!'
@app.route('/path/<path:path>')
def show_path(path):
return f'path {escape(path)}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'Post {post_id}'
if __name__ == '__main__':
app.run(debug=True)
ブラウザ入力http://127.0.0.1:5000/integer/56、出力
整数: 56
ブラウザ入力http://127.0.0.1:5000/path/tmp/index.html、出力
パス: tmp /index.html
5. URL の構築
url_for()
指定された関数を構築するために使用される URL。関数名を最初の引数として取ります。任意の数のキーワード パラメータを受け入れることができ、各キーワード パラメータは URL 内の変数に対応し、不明な変数はクエリ パラメータとして URL に追加されます。
from flask import Flask, request, redirect
from flask import url_for
app = Flask(__name__)
@app.route('/')
def index():
return 'index'
@app.route('/login')
def login():
print(f"in login function, request.values: {request.values}")
return 'login'
@app.route('/user/<username>')
def profile(username):
return f'{username}\'s profile'
with app.test_request_context():
print(url_for('index'))
print(url_for('login'))
print(url_for('profile', username='Xuan Yu'))
url_for('login') は対応する URL を生成します
/
/ログイン
/user/Xuan%20Yu
6. HTTP メソッド: GET、POST など
方法 | 例証する |
---|---|
得る | 暗号化されていない形式でデータをサーバーに送信する、共通 |
頭 | GET と同じですが、応答本文はありません |
役職 | HTML フォーム データをサーバーに送信するために使用されます。POST メソッドによって受信されたデータはサーバーによってキャッシュされません。 |
置く | ターゲット リソースの現在のすべての表現をアップロードされたコンテンツに置き換えます |
消去 | URL で指定されたターゲット リソースの現在の表現をすべて削除します |
デフォルトでは、Flask ルーターは GET
リクエストにのみ応答します。route()
デコレーターの パラメーターを使用して methods
、さまざまな HTTP メソッドを処理します。
ディレクトリ構造 templates/welcome.html。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTTP方法</title>
</head>
<body>
<form action = "http://localhost:5000/login" method = "post">
<p>Enter Name:</p>
<p><input type = "text" name = "username" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
フラスココード:
from flask import Flask, redirect, url_for, request, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('welcome.html')
@app.route('/welcome/<name>')
def welcome(name):
return f'welcome {name}'
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
user = request.form['username']
return redirect(url_for('welcome', name=user))
else:
user = request.args.get('username') # GET方法获取数据
return redirect(url_for('welcome', name=user))
if __name__ == '__main__':
app.run(debug=True)
POST メソッドの場合、次のコードはフォーム データから「username」パラメーターの値を取得します。
ユーザー = request.form['ユーザー名']
GETメソッドの場合、以下のコードでフォームデータから取得した「username」パラメータの値:
ユーザー = request.args.get('ユーザー名')
args
フォーム パラメータのリストを含むディクショナリ オブジェクトです。'username' パラメータに対応する値が/welcome
URLに渡されます。
/login?username=XuanYu
7. テンプレートをレンダリングする render_template()
ディレクトリ構造 templates/render_template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render_template</title>
</head>
<body>
<h2>渲染模板演示</h2>
{
{ my_int }}
<br>
{
{ my_str }}
<br>
{
{ my_list }}
<br>
{
{ my_dict }}
<hr>
<h2>列表数据获取</h2>
{
{ my_list[0] }}
<br>
{
{ my_list.1 }}
<hr>
<h2>字典数据获取</h2>
{
{ my_dict['name'] }}
<br>
{
{ my_dict.age }}
<hr>
<h2>算术运算</h2>
{
{ my_list.0 + 10 }}
<br>
{
{ my_list[0] + my_list.1 }}
</body>
</html>
フラスココードは次のとおりです。
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
int_ = 1024
str_ = 'Hello World!'
list_ = [1, 2, 3, 4, 5]
dict_ = {'name': 'Kint', 'age': 23}
# render_template方法:渲染模板
# 参数1: 模板名称 参数n: 传到模板里的数据
return render_template('render_template.html', my_int=int_, my_str=str_, my_list=list_, my_dict=dict_)
if __name__ == '__main__':
app.run(debug=True)
Flask は、Jinja2 テンプレート エンジンを使用して、公式の Jinja2 テンプレート ドキュメントでテンプレートをレンダリングします。
8. リクエストオブジェクト
ディレクトリ ファイル templates/Request.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Request</title>
</head>
<body>
<form action="/login?a=1&b=2" method="post">
<p>账号: <input type="text" name="username"></p>
<p>密码: <input type="password" name="password"></p>
<input type="submit">
</form>
</body>
</html>
フラスココード:
from flask import Flask, request, render_template
import json
app = Flask(__name__)
@app.route('/')
def index():
return render_template("Request.html")
@app.route('/login', methods=["GET", "POST"])
def login():
print('request.method:\n', request.method)
print('request.data:\n', request.data)
print('request.request.args:\n', request.args)
print("request.request.args.get('b'):\n", request.args.get('c'))
print('request.form:\n', request.form)
print("request.request.form.get('password'):\n", request.form.get('password'))
print('request.values:\n', request.values)
print('request.json:\n', request.json)
print('request.cookies:\n', request.cookies)
print('request.headers:\n', request.headers)
return json.dumps(request.form) # 将MultiDict数据处理为JSON数据
if __name__ == '__main__':
app.run(debug=True)
MultiDict の値を取得する場合、 request.form[key]を直接使用する代わりにrequest.form.get(key)を使用することをお勧めします. 前者の方法では、キーワードの欠落による KeyError を回避できます.
さまざまなパスを取得します。URL はhttp://127.0.0.1:5000/login?a=1&b=2です。
print('url:', request.url)
print('base_url:', request.base_url)print('host_url:', request.host_url)
print('path:', request.path)
print('full_path:', request.full_path)
print('host:', request.host)
出力:
URL: http://127.0.0.1:5000/login?a=1&b=2
base_url: http://127.0.0.1:5000/loginホスト URL: http://127.0.0.1:5000/
パス: /login
フルパス: /login?a=1&b=2
ホスト: 127.0.0.1:5000
9.クッキー
Flask での Cookie の処理手順は次のとおりです。
- Response オブジェクトの set_cookie() メソッドを使用して Cookie を設定する
- request.cookies で Cookie を取得し、辞書を返す
- Response オブジェクトの delete_cookie() メソッドを使用して Cookie を設定します。
テンプレートフォルダーの下の get_cookie.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>获取cookie</title>
</head>
<body>
<h2>在服务端获取cookie: <b>{
{cookie}}</b></h2>
</body>
</html>
テンプレートフォルダーの下の show_cookie_by_JQuery.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>设置cookie</title>
<script src="../static/jquery-3.6.0.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h2>在服务端设置cookie</h2>
<h2>在客户端通过JQuery读取cookie: <b id='cookie'></b></h2>
</body>
<script>
$('#cookie').text(document.cookie);
</script>
</html>
フラスコ生成の下で:
from flask import Flask, request, Response, render_template, make_response, redirect, url_for
app = Flask(__name__)
@app.route('/')
def index():
# 重定向响应的URL
return redirect(url_for('set_cookie'))
# 设置cookie
@app.route('/set_cookie')
def set_cookie():
html = render_template('show_cookie_by_JQuery.html')
response = make_response(html) # 设置响应体
# response = Response(html)
response.set_cookie('user', 'Kint')
return response
# 获取cookie
@app.route('/get_cookie')
def get_cookie():
# 获取关键字为user对应cookie的值
cookie = request.cookies.get('user')
print(cookie)
return render_template('get_cookie.html', cookie=cookie)
# 删除cookie
@app.route('/del_cookie')
def del_cookie():
html = render_template('show_cookie_by_JQuery.html')
response = Response(html)
response.delete_cookie('user')
return response
if __name__ == '__main__':
app.run(debug=True)
set_cookie() 関数では、最初にテンプレート ファイル show_cookie_by_JQuery.html をレンダリングし、レスポンス ボディを設定して、make_response() メソッドを通じて Response オブジェクトを返し、Cookie を設定します。どちらの書き方でも同じ効果があります。
response = make_response(html) # レスポンス本文を設定する
response = Response(html)
10. セッションセッション
Cookie とは異なり、セッション データはサーバーに保存され、ユーザー情報 (ログイン ステータス、ユーザー名など) を保存するために使用されます。セッションにはユーザーに対応する一意の識別 ID があり、対応するユーザーのデータはサーバー側で ID を使用して見つけることができるため、Flask アプリケーションには定義済みのキー SECRET_KEY が必要です。
ユーザーがログインしているかどうかを判断する関数を実装するだけです。
from flask import Flask, redirect, url_for, request, session
app = Flask(__name__)
app.secret_key = 'abc'
@app.route('/')
def index():
if 'user' in session:
# 获取会话中的用户信息
user = session.get('user')
return '登录用户是:' + user + '<br>' + "<b><a href = '/logout'>点击这里注销</a></b>"
return "<h3>暂未登录</h3><br>" + "<a href = '/login'></b>点击这里登录</b></a>"
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 设置会话中的用户信息
session['user'] = request.form['user']
return redirect(url_for('index'))
return '''
<form action="" method="post">
<p><input type="text" name="user"/></p>
<p><input type="submit" value="登录"/></p>
</form>
'''
@app.route('/logout')
def logout():
# 删除会话中的用户信息
session.pop('user')
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)
case1. アップロードフォーム
/app.py
/templates
/login.html
/result.html
app.py:
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def student():
return render_template('login.html')
@app.route('/result',methods = ['POST', 'GET'])
def result():
if request.method == 'POST':
result = request.form #拿到前端传输的表单数据
return render_template("result.html",result = result)
if __name__ == '__main__':
app.run(debug = True)
テンプレート / login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>case1.上传表单数据—登录页面</title>
</head>
<body>
<form action="http://localhost:5000/result" method="POST">
<p>Name <input type = "text" name = "Name" /></p>
<p>Email <input type = "text" name = "Email" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
テンプレート/結果.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>case1.上传表单数据</title>
</head>
<body>
<table border = 1>
{% for key, value in result.items() %}
<tr>
<th> {
{ key }} </th>
<td> {
{ value }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
case2. ダウンロードとアップロード
/app.py
/templates
/index.html
/upload.html
/upload
/download_sample.txt
app.py:
from flask import Flask, render_template, request, send_from_directory
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'upload/'
# 上传文件大小限制为16M,如果超过会抛出异常
app.config['MAX_CONTENT_LENGTH'] = 16 * 1000 * 1000
@app.route('/')
def upload_file():
return render_template('index.html')
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
f = request.files['file']
print(request.files)
# secure_filename检查客户端上传的文件名,确保安全,注意文件名称不要全中文!!!
f.save(os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(f.filename)))
return render_template('upload.html')
else:
return render_template('index.html')
@app.route('/download/<filename>', methods=['GET', 'POST'])
def download(filename):
# as_attachment=True 表示文件作为附件下载
return send_from_directory('./upload', filename, as_attachment=True)
if __name__ == '__main__':
app.run(debug=True)
アップロード機能では、f.saveの機能は、ファイルを指定されたパスに保存することです。アップロードされたファイルの名前を確認するためにsecure_filename を使用する場合は、できるだけ英語の名前に注意してください。
ダウンロード関数では、send_from_directoryメソッドがアップロード ディレクトリ内の指定されたファイルをクライアントに送信し、as_attachment=Trueはファイルが添付ファイルとしてダウンロードされることを示します。
次のコードを使用して、templates フォルダーの下に index.html ファイルを作成します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>实例2.上传下载文件</title>
</head>
<body>
<h3>上传文件</h3>
<form action="http://localhost:5000/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="提交" />
</form>
<h3>下载文件</h3>
<a href="/download/download_sample.txt">download_sample.txt</a>
</body>
</html>
テンプレート / upload.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>case2.上传成功页面</title>
</head>
<body>
<h3>文件上传成功!</h3>
</body>
</html>