Djangoでmiddleware(ミドルウェア)を自作する方法
ミドルウェアとは?
ミドルウェアというといろんな意味がありますが、今回は「Djangoがさまざまなパス(URL)のリクエストをさばくときに、共通で処理をするもの」とします。
サンプルコード
Githubにサンプルコードがあります。ターミナルで
git clone -b custom-middleware https://github.com/yeconnect/django-baby-starter-template.git
バージョン
Python 3.9です
django==3.2
参考
Django公式「ミドルウェア」
ミドルウェアの設定方法
今回のコードではプロジェクトをconfig、アプリケーションをtodoとしています。
ミドルウェアのコードを記載する場所はどこでも良いですが、今回は以下のようなディレクトリとし、ルートにmiddlewareディレクトリを作成し、その中に__init__.py(空で良い)と、sample_middleware.pyを作成しました。
.
├── Dockerfile
├── README.md
├── config
│ ├── __init__.py
│ ├── __pycache__
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── docker-compose.yml
├── manage.py
├── middleware
│ ├── __init__.py
│ ├── __pycache__
│ └── sample_middleware.py
├── requirements.txt
└── todo
├── __init__.py
├── admin.py
├── apps.py
├── migrations
├── models.py
├── tests.py
└── views.py
それでは、ミドルウェア本体を定義します。sample_middleware.pyに以下の記述をします。
class SampleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
print('サーバー起動のときのみ')
def __call__(self, request):
# ここにviews.pyの前にしたい処理を記述
print('1: リクエストがviews.pyで処理される前') # 例
response = self.get_response(request)
# ここにviews.pyの後にしたい処理を記述
print('2: リクエストがviews.pyで処理された後') # 例
return response
これをsettings.pyで読み込みます。40行目あたりにあるMIDDLEWARE = []に追加します。
MIDDLEWARE = [
'middleware.sample_middleware.SampleMiddleware', # 今回の自作ミドルウェア
'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',
]
middleware.sample_middleware.SampleMiddlewareのように、middleware.ファイル名.クラス名で読み込めます。
実際に走らせてみる
サンプルコードで体験してみましょう。ターミナルで、
git clone -b custom-middleware https://github.com/yeconnect/django-baby-starter-template.git
cd django-baby-starter-template
docker compose up
とし、ブラウザで http://localhost:4989/todo/ を表示させます。
このURLでは、views.pyで
def sample_func(request):
print('ここがviews.py、sample_funcなう')
return HttpResponse('Hello World from todo app')
とprintさせるようにしています。
ターミナルを見ると
と表示されています。
解説
自作するミドルウェアクラスでは、以下の①、②、③の3つの記述ポイントがあります。
class SampleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# ① サーバー起動時にしたい処理をここに
def __call__(self, request):
# ② リクエスト処理前にしたい処理をここに
response = self.get_response(request) # これはviews.pyでの処理を意味する
# ③ リクエスト処理後にしたい処理をここに
return response
ここからの記事では②を「前処理」、③を「後処理」と言います。
ミドルウェアの実行される順番
ここまでは一つのミドルウェアについて見てきました。
Djangoでは、複数のミドルウェアを作ることもできます。その順番は、書く順番によって決まります。
MIDDLEWARE = [
'ミドルウェアA',
'ミドルウェアB',
'ミドルウェアC'
]
のように書いたとすると
ミドルウェアAの前処理 → ミドルウェアBの前処理 → ミドルウェアCの前処理 → views.pyでの処理 → ミドルウェアCの後処理 → ミドルウェアBの後処理 → ミドルウェアAの後処理
のようになります。Django公式では「views.pyが中央のコアにある、玉ねぎのような構造」とあります。
おまけ
この自作ミドルウェアを応用して「Djangoがレスポンスを返すまでにかかった時間を測定してみた!」を作成しました。middlewareを実際に使うところが見たい場合はこちらをご覧ください。(サンプルコードもあります。)
スポンサーリンク
ディスカッション
コメント一覧
まだ、コメントがありません