今回のお題
今回はdjangoのmiddlewareについてまとめます。
最近middlewareについて学習する機会があったのですが、なぜそのように記述するとmiddlewareが動作するのかが理解できませんでした。
原理を解っていた方が応用も効きますし覚えるのも楽だと思うので、今回はmiddlewareの基礎的な部分についてまとめます。
目次
- middlewareとは
- middlewareの書き方(関数ベース)
- middlewareの書き方(クラスベース)
- middlewareの登録
middlewareとは
まずはmiddlewareそのものの定義を確認しておきます。
middlewareとは「リクエストの前後に実行される共通の処理をまとめたもの」を指します。
djangoではリクエストに応じて様々な関数(もしくはテンプレートビュークラス)が呼び出され、それらの場合分けはurls.py
とviews.py
によって行われています。
つまり、リクエストの内容によって実行される関数は変わります。
それに対してどのようなリクエストに対しても実行される処理が書かれているのがmiddleware
というわけです。
では、概要がわかったところでmiddlewareを書いていきます。
middlewareの書き方(関数ベース)
middlewareの書き方には、関数ベースとクラスベースがあります。
ちょうどビューと同じですね。
ビューの関数ベースとクラスベースについては以下をどうぞ。
では、middleware.pyというファイルをアプリケーション側に作成し、中身を書いていきます。
def factory(get_response):
# 処理1
def middleware(request):
# 処理2
response = get_response(request)
# 処理3
return response
return middleware
まずmiddleware全体の構造ですが、middlewareファクトリー
と呼ばれる関数で中央のmiddleware関数
本体がラップされ、中心にはresponse = get_response(request)
という一文があります。
そしてそれらを境界として処理1 ~ 3
とコメントをつけた領域があります。
これらの役割は以下の通りです。
- 処理1:サーバー起動時に一度だけ行いたい処理を記述
- 処理2:レスポンスを実行する前に行いたい処理を記述
- 処理3:レスポンスを実行した後に行いたい処理を記述
具体例は以下(実用性は全く考慮していません)。
def factory(get_response):
# 処理1
print("サーバーが立ち上がりました")
def middleware(request):
# 処理2
print("リクエストが行われました")
response = get_response(request)
# 処理3
print("レスポンスが完了しました")
return middleware
では、次にクラスベースの書き方も見ていきましょう。
middlewareの書き方(クラスベース)
クラスベースのmiddlewareは以下のように記述します。
class Middleware:
def __init__(self, get_response):
# 処理1
self.get_response = get_response
def __call__(self, request):
# 処理2
response = self.get_response(request)
# 処理3
return response
クラスベースの場合には、__init__
メソッドと__call__
メソッドを定義してその中に処理を書きます。
ちなみに__init__
メソッドはサーバー起動時に一度だけ呼ばれ、__call__
メソッドはリクエストのたびに都度実行されます。
middlewareの登録
上記の作業でmiddlewareの作成は完了しました。
ただ、これだけではプロジェクトから存在を認識されていないので設定ファイルに登録する必要があります。
MIDDLEWARE = [
# 既存のmiddleware
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 追加
"xxx.middleware.factory", # 関数ベース
# クラスベースの場合には以下のように記述
# " xxx.middleware.Middleware", # xxxはアプリケーション名
]
もともといくつかのmiddlewareが登録されておりこれらは何もしなくても実行されるようになっています。
このmiddlewareリストに先ほど作成したものも追加してあげることで、初めてmiddlewareが実行されるようになります。
余談ですが、この部分におけるmiddlewareの登録順序は実際の実行順序と関わっているようです。
具体的にいうと、リクエストが行われた際には上から下に、逆にレスポンスを返した後には下から上にという順序で実行されます。
終わりに
というわけで、以上がmiddlewareのお話でした。
もちろん今回の内容は超基本的なもので、まだまだ応用的な部分はたくさんあります。
そちらについては気が向いたらまとめようかなと思います。