- Django ミドルウェア
- カスタム ミドルウェア
- process_request
- process_response
- process_view
- process_exception
- process_template_response (あまり使用されない)
- ミドルウェア版ログイン検証
- Django リクエスト フロー図
カスタム ミドルウェア
カスタム ミドルウェアには5つのメソッドを定義できます。主なものはprocess_requestとprocess_responseです。
- process_request(self, request)
- process_view(self, request, view_func, view_args, view_kwargs)
- process_template_response(self, request, response)
- process_exception(self, request, exception)
- process_response(self, request, response)
これらのメソッドの戻り値はNoneまたはHttpResponseオブジェクトです。Noneの場合、通常のフローが続き、次のミドルウェアが処理されます。HttpResponseオブジェクトの場合、直接ユーザーに返されます。
ミドルウェアはDjangoのリクエストとレスポンスを処理するためのフレームワーク レベルのフックです。基本的に、ミドルウェアはクラスです。
4つの特徴に注意します:実行時、実行順序、パラメータ、戻り値。
カスタム ミドルウェアの例
from django.utils.deprecation import MiddlewareMixin
class CustomMiddleware1(MiddlewareMixin):
def process_request(self, request):
print("CustomMiddleware1のprocess_requestを実行")
def process_response(self, request, response):
print("CustomMiddleware1のprocess_responseを実行")
return response
process_request
process_requestの引数はrequestです。これはビュー関数と同じrequestオブジェクトです。
戻り値はNoneまたはHttpResponseオブジェクトです。Noneの場合、通常のフローが続き、ビュー関数が実行されます。
HttpResponseオブジェクトの場合、ビュー関数は実行されず、直接レスポンスが返されます。
複数のミドルウェアを配置した場合、Djangoは以下のようにprocess_requestメソッドを実行します。
from django.utils.deprecation import MiddlewareMixin
class CustomMiddleware1(MiddlewareMixin):
def process_request(self, request):
print("CustomMiddleware1のprocess_requestを実行")
class CustomMiddleware2(MiddlewareMixin):
def process_request(self, request):
print("CustomMiddleware2のprocess_requestを実行")
settings.pyのMIDDLEWARE設定に上記の2つのカスタム ミドルウェアを登録します。
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',
'middlewares.CustomMiddleware2',
'middlewares.CustomMiddleware1',
]
ビュー関数をアクセスすると、ターミナルに以下のような出力が表示されます。
CustomMiddleware2のprocess_requestを実行
CustomMiddleware1のprocess_requestを実行
app01のindexビュー関数を実行
process_requestメソッドはビュー関数の前に実行されます。複数のミドルウェアを配置した場合、MIDDLEWAREリストの順序に従って実行されます。異なるミドルウェア間で共有されるrequestは同じオブジェクトです。
process_response
process_responseの引数はrequestとresponseです。
requestはビュー関数と同じオブジェクトです。
responseはビュー関数から返されたHttpResponseオブジェクトです。
戻り値はHttpResponseオブジェクトでなければなりません。
上記のCustomMiddleware1とCustomMiddleware2にprocess_responseメソッドを追加します。
class CustomMiddleware1(MiddlewareMixin):
def process_request(self, request):
print("CustomMiddleware1のprocess_requestを実行")
def process_response(self, request, response):
print("CustomMiddleware1のprocess_responseを実行")
return response
class CustomMiddleware2(MiddlewareMixin):
def process_request(self, request):
print("CustomMiddleware2のprocess_requestを実行")
def process_response(self, request, response):
print("CustomMiddleware2のprocess_responseを実行")
return response
ビュー関数をアクセスすると、ターミナルに以下のような出力が表示されます。
CustomMiddleware2のprocess_requestを実行
CustomMiddleware1のprocess_requestを実行
app01のindexビュー関数を実行
CustomMiddleware1のprocess_responseを実行
CustomMiddleware2のprocess_responseを実行
process_responseメソッドはビュー関数の後に実行されます。複数のミドルウェアを配置した場合、MIDDLEWAREリストの順序に逆順で実行されます。
process_view
process_viewの引数はrequest、view_func、view_args、view_kwargsです。
requestはHttpRequestオブジェクトです。
view_funcはDjangoが使用するビュー関数です。
view_argsはビュー関数に渡される位置引数のリストです。
view_kwargsはビュー関数に渡されるキーワード引数の辞書です。
Djangoはビュー関数を実行する前にprocess_viewメソッドを呼び出します。
戻り値はNoneまたはHttpResponseオブジェクトです。
CustomMiddleware1とCustomMiddleware2にprocess_viewメソッドを追加します。
class CustomMiddleware1(MiddlewareMixin):
def process_request(self, request):
print("CustomMiddleware1のprocess_requestを実行")
def process_response(self, request, response):
print("CustomMiddleware1のprocess_responseを実行")
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print("-" * 80)
print("CustomMiddleware1のprocess_viewを実行")
print(view_func, view_func.__name__)
class CustomMiddleware2(MiddlewareMixin):
def process_request(self, request):
print("CustomMiddleware2のprocess_requestを実行")
def process_response(self, request, response):
print("CustomMiddleware2のprocess_responseを実行")
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print("-" * 80)
print("CustomMiddleware2のprocess_viewを実行")
print(view_func, view_func.__name__)
ビュー関数をアクセスすると、ターミナルに以下のような出力が表示されます。
CustomMiddleware2のprocess_requestを実行
CustomMiddleware1のprocess_requestを実行
--------------------------------------------------------
CustomMiddleware2のprocess_viewを実行
<function index at 0x...> index
--------------------------------------------------------
CustomMiddleware1のprocess_viewを実行
<function index at 0x...> index
app01のindexビュー関数を実行
process_viewメソッドはprocess_requestの後に、ビュー関数の前に実行されます。実行順序はMIDDLEWAREリストの順序に従って実行されます。
process_exception
process_exceptionの引数はrequestとexceptionです。
requestはHttpRequestオブジェクトです。
exceptionはビュー関数で発生した例外です。
戻り値はNoneまたはHttpResponseオブジェクトです。
ビュー関数で例外を発生させる例:
def index(request):
print("app01のindexビュー関数を実行")
raise ValueError("エラー発生")
return HttpResponse("OK")
CustomMiddleware1にprocess_exceptionメソッドを追加します。
class CustomMiddleware1(MiddlewareMixin):
def process_request(self, request):
print("CustomMiddleware1のprocess_requestを実行")
def process_response(self, request, response):
print("CustomMiddleware1のprocess_responseを実行")
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print("-" * 80)
print("CustomMiddleware1のprocess_viewを実行")
print(view_func, view_func.__name__)
def process_exception(self, request, exception):
print("例外発生:", exception)
print("CustomMiddleware1のprocess_exceptionを実行")
return HttpResponse(str(exception))
ビュー関数をアクセスすると、ターミナルに以下のような出力が表示されます。
CustomMiddleware2のprocess_requestを実行
CustomMiddleware1のprocess_requestを実行
--------------------------------------------------------
CustomMiddleware2のprocess_viewを実行
<function index at 0x...> index
--------------------------------------------------------
CustomMiddleware1のprocess_viewを実行
<function index at 0x...> index
app01のindexビュー関数を実行
例外発生: ValueError("エラー発生")
CustomMiddleware1のprocess_exceptionを実行
CustomMiddleware1のprocess_responseを実行
CustomMiddleware2のprocess_responseを実行
process_template_response (あまり使用されない)
process_template_responseの引数はrequestとresponseです。
responseはTemplateResponseオブジェクトです。
Djangoはビュー関数を実行した後にprocess_template_responseメソッドを呼び出します。
戻り値はHttpResponseオブジェクトでなければなりません。
ミドルウェア版ログイン検証
ログイン検証はセッションを使用します。したがって、データベースにdjango_sessionテーブルが必要です。
ビュー関数の例:
def login(request):
if request.method == "POST":
user = request.POST.get("user")
pwd = request.POST.get("pwd")
if user == "admin" and pwd == "admin123":
request.session["user"] = user
next_url = request.GET.get("next")
if next_url:
return redirect(next_url)
else:
return redirect("/index/")
return render(request, "login.html")