1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

djangoのmiddlewareについてざっくりまとめる

Posted at

今回のお題

今回はdjangoのmiddlewareについてまとめます。

最近middlewareについて学習する機会があったのですが、なぜそのように記述するとmiddlewareが動作するのかが理解できませんでした。

原理を解っていた方が応用も効きますし覚えるのも楽だと思うので、今回はmiddlewareの基礎的な部分についてまとめます。

目次

  • middlewareとは
  • middlewareの書き方(関数ベース)
  • middlewareの書き方(クラスベース)
  • middlewareの登録

middlewareとは

まずはmiddlewareそのものの定義を確認しておきます。

middlewareとは「リクエストの前後に実行される共通の処理をまとめたもの」を指します。

djangoではリクエストに応じて様々な関数(もしくはテンプレートビュークラス)が呼び出され、それらの場合分けはurls.pyviews.pyによって行われています。

つまり、リクエストの内容によって実行される関数は変わります。

それに対してどのようなリクエストに対しても実行される処理が書かれているのがmiddlewareというわけです。

では、概要がわかったところでmiddlewareを書いていきます。

middlewareの書き方(関数ベース)

middlewareの書き方には、関数ベースとクラスベースがあります。

ちょうどビューと同じですね。

ビューの関数ベースとクラスベースについては以下をどうぞ。

では、middleware.pyというファイルをアプリケーション側に作成し、中身を書いていきます。

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:レスポンスを実行した後に行いたい処理を記述

具体例は以下(実用性は全く考慮していません)。

middleware.py
def factory(get_response):
  # 処理1
  print("サーバーが立ち上がりました")
  def middleware(request):
    # 処理2
    print("リクエストが行われました")
    response = get_response(request)
    # 処理3
    print("レスポンスが完了しました")
  return middleware

では、次にクラスベースの書き方も見ていきましょう。

middlewareの書き方(クラスベース)

クラスベースのmiddlewareは以下のように記述します。

middleware.py
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の作成は完了しました。

ただ、これだけではプロジェクトから存在を認識されていないので設定ファイルに登録する必要があります。

settings.py
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のお話でした。

もちろん今回の内容は超基本的なもので、まだまだ応用的な部分はたくさんあります。

そちらについては気が向いたらまとめようかなと思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?