DjangoでMiddlewareを複数指定した場合どのような順序でコードが実行されるのか気になったので試してみた。
実験コード
settings.py
設定ファイルの抜粋
MIDDLEWARE = (
# ・・・・諸々のMiddleware,
"middleware.Middleware1",
"middleware.Middleware2",
)
middleware.py
middlewareを2つ定義
class Middleware1:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
print("M1 before")
response = self.get_response(request)
print("M1 after")
return response
class Middleware2:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
print("M2 before")
response = self.get_response(request)
print("M2 after")
return response
hoge.py
テキトーなView
from django.http import HttpResponse
from django.views import View
class Hoge(View):
def get(self, request):
print("View")
return HttpResponse()
実験結果
Hoge View に対応するエンドポイントにリクエストした結果
M1 before
M2 before
View
M2 after
M1 after
- 設定ファイルで定義したMiddlewareの順に、入れ子になるような形で
__call__
が実行される。 - Viewのコードは入れ子の真ん中で一度だけ実行される。
書いた後で気づいたけど、こちらの記事にも同様の事実を示す下記の記載があった。
また、Middlewareはリクエストが送られたらこのsettings.pyに設定されているものを上から順番に(2)に書かれた処理が実行されます。一方で(3)に書かれた処理はこの逆の順番で実行されます。なので場合によってはこの順番を意識して設定する必要があります。
(入れ子になっている様子がよくわかったのでまぁいいか・・。)