Djangoでは、アプリ、context_processorsなど様々なプラグイン機能が提供されており、画一的なフレームワークの中でソフトウェアを実装することで効率化・高可搬性を実現しています。
しかし、一旦システムを実装開始すると、システムは様々な環境が依存しあうもので、一つの関数を書き換えると様々なビューやテンプレートファイルに修正範囲が波及する。。。なんてことがよく起こります。
せっかくMVCフレームワークを提供しているのに、それを正しく使わないのが悪い!などと怒られそうですが、理想と現実は異なる訳で、プラットフォームにはそのどちらもフォローできる柔軟な環境が求められます。
既存のシステム全てに共通で処理をフックしたり、テンプレート変数を追加したい。。。などということを実現するにはどうしたら良いのでしょうか?
これを簡単に実現できる方法がDjangoにはあります。
それがミドルウェアです。
ミドルウェアは大まかに言うと、 ビューをコールする直前と直後にフックを入れることができる機能 です。従って、全てのビューにある特定のテンプレート変数を追加・変更したり、共通の処理を追加することが可能です。
ミドルウェアを追加する場合、
といった手順を経る必要があります。
まずはsettings.pyにミドルウェアを登録しましょう。
$ emacs settings.py
...
MIDDLEWARE_CLASSES = (
...,
'hoge_app.middlewares.hookfunc',
)
次に、実態 hookfunc クラスを実装します。
$ emacs hoge_app/middlewares.py
class hookfunc():
def __init__(self):
pass
def process_request(self, request):
"""
どのviewを実行するか決定する前にコールされるフック。
"""
return None # 処理継続
# return request # ここで処理終了
def process_view(self, request, view_func, view_args, view_kwargs):
"""
実行されるviewが決定した後にコールされるフック。
"""
return None # 処理継続
# return response # ここで処理終了
def process_response(self, request, response):
"""
viewを実行した後に呼びだされるフック。
"""
return response # ここで処理終了
ミドルウェアクラスでは、予めI/Fとして定義されている
をオーバーライドすることで、実行されるタイミングが決定されます。
また、返り値としてNoneを返すと次のミドルウェアクラスのハンドラを実行し、
requestオブジェクトやresponseオブジェクトを返すと、そこで処理が完了するといった処理を実現することも可能です。