revision-up-to: | 17812 (1.4) |
---|
ミドルウェア (Middleware) とは、 Django のリクエスト/レスポンス処理をフック するためのフレームワークです。ミドルウェアは軽量かつ低水準な「プラグイン」 システムで、Django の入出力を操作します。
各ミドルウェアコンポーネントはそれぞれ特定の機能を担っています。例えば、
Django には XViewMiddleware
ミドルウェアコンポーネントがありますが、こ
れは全ての HEAD
リクエストに対して "X-View"
HTTP ヘッダを追加します。
このドキュメントでは、 Django についてくる全てのミドルウェアコンポーネント の使用法と、自分で新たにミドルウェアを作る方法を説明します。 Django には、すぐに使える組み込みのミドルウェアが付属しています。 組み込みミドルウェアガイド を参照してください。
ミドルウェアコンポーネントを有効化するには、Django 設定ファイルの
MIDDLEWARE_CLASSES
リストにコンポーネントを追加します。コンポー
ネント名は文字列で指定し、ミドルウェアのクラス名を完全な Python パスで表し
ます。例えば、 django-admin.py startproject
が生
成するデフォルトの設定ファイルにある MIDDLEWARE_CLASSES
は以下の
ようになっています:
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
リクエストの処理フェーズでは、Django は MIDDLEWARE_CLASSES
に指定された順番で (process_request()
および process_view`()
)
ミドルウェアを適用していきます。レスポンスの処理フェーズでは、
(process_response()
および process_exception()
) ミドルウェア
が逆順に適用されます。この仕組みは、タマネギの構造になぞらえて、ミドルウェ
アクラスを「層」だと考えるとよいでしょう:
Django はミドルウェアがなくても動作します – 望むなら
MIDDLEWARE_CLASSES
は空でもよいのです。とはいえ、少なくとも
CommonMiddleware
は使うように強く勧めます。
ミドルウェアの自作は簡単です。各ミドルウェアコンポーネントは、以下のメソッ ドを少なくとも一つ定義しているような単一の Python クラスです:
process_request
¶process_request
(self, request)¶request
は HttpRequest
オブジェクトです。このメソッ
ドはリクエストごとに Django がどのビューを実行するか決定する前に呼び出されます。
process_request()
は None
または HttpResponse
オブジェクトのいずれかを返さねばなりません。 None
を返した場合、 Django
はリクエストの処理を継続し、他のミドルウェアや適切なビューを実行します。
HttpResponse
オブジェクトを返した場合、 Django は他の
リクエストミドルウェア、ビューミドルウェア、例外ミドルウェア、あるいは
URLconf で設定されたビューを呼び出さず、 HttpResponse
オブジェクトをそのまま返します。レスポンスミドルウェアは必ず呼び出されます。
process_view
¶process_view
(self, request, view_func, view_args, view_kwargs)¶request
は HttpRequest
オブジェクトです。
view_func
は Django がビュー関数としてこれから呼び出そうとしている
Python の関数です、 (実際の関数オブジェクトで、関数名を表す文字列ではありま
せん)。 view_args
にはビューに渡されることになる固定引数が、
view_kwargs
にはビューに渡されることになるキーワード引数の辞書が入って
います。 view_args
と``view_kwargs`` のいずれにも、ビューの第一引数
(request
) は入っていません。
process_view()
は Django がビュー関数を呼び出す直前に呼び出されます。こ
の関数は None
または HttpResponse
オブジェクトを
返さねばなりません。 None
を返した場合、 Django は処理を継続し、他のミ
ドルウェアの process_view()
を試した後、適切なビュー関数を呼び出します。
HttpResponse
オブジェクトを返した場合、 Django は他の
リクエストミドルウェア、ビューミドルウェア、例外ミドルウェア、あるいは
URLconf で設定されたビューを呼び出さず、 HttpResponse
オブジェクトをそのまま返します。レスポンスミドルウェアは必ず呼び出されます。
Note
process_request
や``process_view`` からミドルウェアの中の
request.POST
や
request.REQUEST
にアクセスするとそのミドルウェアの後で実行される任意のビューが
リクエストのアップロードハンドラーを動的に変更する ことができなくなるので避けるべきです。
CsrfViewMiddleware
クラスは例外と
考えることができます。
csrf_exempt()
デコレータと
csrf_protect()
デコレータでは
ビューはCSRF検証が行われる時点で明示的に制御することができるからです。
process_template_response
¶リリースノートを参照してください
process_template_response
(self, request, response)¶request
は HttpRequest
クラスのオブジェクトです。
response
は SimpleTemplateResponse
クラスのサブクラス (例えば TemplateResponse
)
、あるいは render
メソッドを実装する任意の response オブジェクトです。
process_template_response()
は render
メソッドを実装する response
オブジェクト返さなければいけません。
与えられた response
の response.template_name
と
response.context_data
を変更することができますが、 全くあたらしい
SimpleTemplateResponse
か同等のものを
作成することも可能です。
process_template_response()
は response インスタンスが render()
メソッド
を持っている時、つまりそのresponse が
TemplateResponse
クラス、あるいは同等のクラス
であるのみ呼び出されます。
明示的にresponseをレンダする必要はありません。 – 全てのテンプレート応答ミドルウェア が呼び出された時に1度だけ自動的にresponseがレンダされます。
応答フェーズの間、ミドルウェアは逆順で実行されます。 process_template_response もそれに含まれます。
process_response
¶process_response
(self, request, response)¶request
は HttpRequest
オブジェクトです。
response
は Django のビュー関数の返す
HttpResponse
オブジェクトです。
process_response()
は HttpResponse
オブジェクトを
返さねばなりません。渡された response
オブジェクトを変更して返しても良いですし、
新たに HttpResponse
オブジェクトを生成して返すことも可能です。
process_request()
や process_view()
メソッドとは異なって、
process_response()
メソッドは必ず呼ばれます。
同じミドルウェアクラスの process_request()
や process_view()
メソッド
がスキップされても呼ばれます。これより先に呼ばれるミドルウェアメソッドが
httpresponse
クラスを返していたからです(つまり、例えば
process_response()
メソッドは process_request()
でセットアップが
完了していることを前提としてはいけない、ということです。)
さらに、レスポンスフェーズの間はクラスは逆順、つまり下から上に適用されます。
これは MIDDLEWARE_CLASSES
の最後に定義されたクラスが最初に
実行されるという意味です。
process_exception
¶process_exception
(self, request, exception)¶request
は HttpRequest
オブジェクトです。
exception
はビュー関数の送出した Exception
オブジェクトです。
Django はビューが例外を送出した際に process_exception()
を呼び出します。
process_exception()
は None
または
HttpResponse
オブジェクトのいずれかを返さねばなりませ
ん。 HttpResponse
オブジェクトを返した場合、その応答
をそのままブラウザに返します。それ以外の場合、デフォルトの例外処理を起動し
ます。
ここでも応答フェーズの間はミドルウエアは逆順で実行されます。
process_exception
もそれに含まれます。
もしも例外ミドルウェアが応答を返すのであれば、
そのミドルウェアより上位にあるミドルウェアクラスは決して呼ばれることはありません。
__init__
¶ほとんどのミドルウェアクラスは、実質的に単なる process_*
メソッドの置き
場でしかないので、初期化メソッドは必要ありません。ミドルウェアのグローバル
な状態を保存するのに __init__
メソッドを使ってもかまいませんが、以下の
点に注意してください:
__init__
には必須の引数を定義できません。process_*
メソッドはリクエストごとに呼び出されますが、
__init__
は Web サーバの起動時に 一度 しか呼び出されません。ミドルウェアを使うかどうかを実行時に決められると便利なことがあります。ミド
ルウェアの __init__
メソッドで
django.core.exceptions.MiddlewareNotUsed
を送出すると、 Django はそ
のミドルウェアを処理から外します。
MIDDLEWARE_CLASSES
にクラスへの
パスが指定されていることだけです。Django で使えるミドルウェア
を参考にしてく
ださい。Oct 26, 2017