Flask を使い始めるための基本

目次

0. ウェブの動作原理とフラスコの関係

 B/S および C/S アーキテクチャ

 ウェブのしくみ

1.フラスコをインストールする

2. 基本的な枠組み

3. @app.route('') のルーティング

4. 可変ルール

5. URL の構築

6. HTTP メソッド: GET、POST など

7. テンプレートをレンダリングする render_template()

8. リクエストオブジェクト

9.クッキー

10. セッションセッション

case1. アップロードフォーム

case2. ダウンロードとアップロード



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 の処理手順は次のとおりです。

  1. Response オブジェクトの set_cookie() メソッドを使用して Cookie を設定する
  2. request.cookies で Cookie を取得し、辞書を返す
  3. 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>

おすすめ

転載: blog.csdn.net/weixin_40011280/article/details/129271589