40、flask--Flaskコンテキスト

4532 ワード

Flaskコンテキスト:
1、Localオブジェクト:
`Flask`では、`request`のようなオブジェクトが`werkzeugにバインドされています.local.Local`オブジェクト上.これにより、同じオブジェクトでも複数のスレッドで分離されます.似たような対象には`session`と`g`の対象があります.
2、Thread Localオブジェクト:
このオブジェクトにバインドされた属性を満たし、各スレッドで隔離されている限り、彼は`Thread Local`オブジェクトと呼ばれます.
サンプルコード:
from threading import Thread
from werkzeug.local import Local

local = Local()

local.request = '123'

class MyThread(Thread):
    def run(self):
        local.request = 'abc'
        print('   :',local.request)

mythread = MyThread()
mythread.start()
mythread.join()

print('   :',local.request)

実行結果
   : abc
   : 123

3、適用コンテキストと要求コンテキスト:
アプリケーションコンテキストとリクエストコンテキストは、いずれも`LocalStack`のスタックに格納されます.アプリケーションappに関連する操作は、`current_などのアプリケーションコンテキストに使用する必要があります.app`は現在のこの`app`を取得します.リクエストに関連する操作は、`url_を使用するなど、リクエストコンテキストに使用する必要があります.for`ビュー関数を反転します.        1. ビュー関数では、コンテキストの問題を心配する必要はありません.ビュー関数が実行されるため、urlにアクセスすることで実行されるに違いありません.この場合、Flaskの最下位層は、要求コンテキストとアプリケーションコンテキストを対応するスタックに自動的にプッシュしてくれます.        2. 現在のapp(current_app)を取得したりurlを反転したりするなど、ビュー関数の外で関連する操作を実行する場合は、関連するコンテキストを手動で押し込む必要があります:*手動でappコンテキストを押し込む:
#      :
app_context = app.app_context()
app_context.push()
#      :
with app.app_context():
     print(current_app)

*手動による要求コンテキストのプッシュ:要求コンテキストをスタックにプッシュすると、まず適用コンテキストがあるかどうかを判断し、ない場合は適用コンテキストをスタックにプッシュしてから、要求コンテキストをスタックにプッシュします.
@app.route('/')
def index():
    print(url_for("my_list"))
    return "Hello World"

@app.route('/list/')
def my_list():
    return "my list"

with app.test_request_context():
    #                    
    #                   
    #                  
    print(url_for('my_list'))

4、コンテキストをスタックに配置する必要がある理由:
       1. 適用コンテキスト:Flaskの下部はwerkzeugに基づいており、werkzeugは複数のappを含むことができるので、この場合はスタックで保存します.app 1を使用している場合は、app 1はスタックの上部にあるはずです.app 1が切れたら、app 1はスタックから削除する必要があります.他のコードで次のappを使用するのに便利です.       2. テストコードを書いたり、オフラインスクリプトを書いたりするときに、複数のリクエストコンテキストを作成する必要がある場合があります.この場合、スタックに保存する必要があります.どのリクエストコンテキストを使用するかは、対応するリクエストコンテキストをスタックの上部に配置し、使い終わったらこのリクエストコンテキストをスタックから削除します.
5、グローバルオブジェクトのgオブジェクトを保存する:
gオブジェクトはFlaskアプリケーションの実行中に使用できます.そして彼もrequestと同じようにスレッドで隔離されています.このオブジェクトは、開発者自身が定義したデータを格納するために使用され、Flaskプログラム全体で使用できるようにします.一般的には、よく使われるデータを上にバインドして、後でgの上から直接取ればいいので、パラメータの形式を通過する必要がなく、より便利です.
サンプルコード:
@app.route('/')
def index():
    # print(current_app.name)
    # print(url_for('my_list'))
    username = request.args.get('username')
    g.username = username
    log_a()
    log_b()
    log_c()
    return 'Hello World'

util.py中
from flask import g

def log_a():
    print('log a %s' % g.username)

def log_b():
    print('log b %s' % g.username)

def log_c():
    print('log c %s' % g.username)

6、よく使うフック関数:
Flaskでのフック関数は、特定のデコレーションを使用して装飾された関数です.なぜフック関数と呼ぶのかというと、フック関数は正常に実行されるコードに、自分が実行したいコードを挿入することができるからです.では、この関数をフック関数と呼びます.(hook) 1. `before_first_request`:Flaskプロジェクトの最初の導入後に実行されるフック関数.2. `before_request`:リクエストはFlaskに到着しましたが、まだ特定のビュー関数に入る前に呼び出されていません.一般的にこれはビュー関数の前に、後で必要なデータを先に処理して、ビュー関数の使用を便利にすることができます.3. `context_processor`:このフック関数を使用するには、辞書を返さなければなりません.この辞書の値はすべてのテンプレートで使用できます.このフック関数の関数は、多くのテンプレートで使用される変数がある場合、各ビュー関数の`render_ではなく、このフック関数を使用して返すことができます.template`に書くと、コードをより簡潔に維持することができます.4.`errorhandler`:いくつかの異常が発生した場合、例えば404エラー、例えば500エラー.では、これらのエラーを優雅に処理したいなら、`errorhandler`を使って出てくることができます.注意点:*errorhandler装飾のフック関数の下で、対応するステータスコードを返すことを忘れないでください.*errorhandler装飾のフック関数では、エラーの情報を受信するためにパラメータを書く必要があります.パラメータがなければ、直接エラーを報告します.*使用`flask.abort`は、開発者がパラメータが正しくないことを発見したときに400エラーを手動で投げ出すなど、対応するエラーを手動で投げ出すことができます.サンプルコードは次のとおりです.
@app.before_first_request
def first_request():
    print('hello world')

@app.before_request
def before_request():
    # print('                ')
    user_id = session.get('user_id')
    if user_id:
        g.user = 'zhiliao'

@app.context_processor
def context_processor():
    if hasattr(g,'user'):
        return {"current_user":g.user}
    else:
        return {}


@app.errorhandler(500)
def server_error(error):
    return render_template('500.html'),500

@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'),404

@app.errorhandler(400)
def args_error(error):
    return '       '