---
title: "ミドルウェア (Middleware)"
version: 2.1
locale: ja
source: https://docs.djangoproject.com/ja/2.1/topics/http/middleware/
canonical: https://djangodocs.dev/ja/2.1/topics/http/middleware/
---
# ミドルウェア (Middleware)

ミドルウェアは、Django のリクエスト/レスポンス処理にフックを加えるためのフレームワークです。これは、Django の入力あるいは出力をグローバルに置き換えるための、軽量で低レベルの「プラグイン」システムです。

各ミドルウェアのコンポーネントは、それぞれある特定の機能を実行する役目を持っています。たとえば、Django には [`AuthenticationMiddleware`](/ja/2.1/ref/middleware/#django.contrib.auth.middleware.AuthenticationMiddleware) というミドルウェアコンポーネントがあります。このミドルウェアは、セッションを利用して、リクエストとユーザーとを関連付けます。

このドキュメントでは、ミドルウェアが機能するしくみ、ミドルウェアを有効にする方法、そして、自分でミドルウェアを書く方法について説明します。Django には組み込みのミドルウェアがいくつか用意されているので、自分で書かなくてもすぐに使い始めることができます。これらの組み込みのミドルウェアについては、[組み込みミドルウェアリファレンス](/ja/2.1/ref/middleware/) にドキュメントされているので参照してください。

## 自分でミドルウェアを書く

ミドルウェアファクトリは、ミドルウェアを返す `get_response` を取るカラブルです。ミドルウェアは (ビューと同じように) リクエストを受け取ってレスポンスを返すカラブルです。

ミドルウェアは、以下のように関数として書くことができます:

```
def simple_middleware(get_response):
    # One-time configuration and initialization.

    def middleware(request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

    return middleware
```

もしくは、カラブルをインスタンスとして持つクラスとして書くこともできます:

```
class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response
```

Django によって渡される `get_response` カラブルは、実際の (これがミドルウェアの最後にリストアップされている場合) ビューか、チェーン内の次のミドルウェアの可能性があります。現在のミドルウェアはこれが何かを知る必要も気にする必要もなく、ただ次に来るものを表します。

上記は、わずかに単純化したものです -- チェーン内の際にリストアップされたミドルウェアに対する `get_response` は実際のビューではなく [ビューミドルウェア](#view-middleware) を適用する処理を行うハンドラからのラッパーメソッドです。これは適切な URL 属性でビューを呼び出し、[テンプレートレスポンス](#template-response-middleware) と [例外](#exception-middleware) を適用します。

ミドルウェアは、あなたの Ptyhon パスのどこでも使うことができます。

### `__init__(get_response)`

ミドルウェアファクトリは `get_response` 引数を受け取る必要があります。ミドルウェアに対してグローバルな宣言を初期化することもできます。いくつかの注意事項があります:

- Django は `get_response` 引数でミドルウェアを初期化するため、`__init__()` で他の引数を必須にすることはできません。
- リクエストごとに 1 回呼ばれる `__call__()` メソッドとは異なり、`__init__()` はウェブサーバが起動したときに *1回だけ* 呼ばれます。

### ミドルウェアを不使用としてマークする

起動時にミドルウェアを使うかどうかを決めることは、ときに有用です。この場合、ミドルウェアの `__init__()` メソッドが [`MiddlewareNotUsed`](/ja/2.1/ref/exceptions/#django.core.exceptions.MiddlewareNotUsed) を投げる可能性があります。Django はミドルウェアプロセスからこのミドルウェアを削除し、[`DEBUG`](/ja/2.1/ref/settings/#std-setting-DEBUG) が `True` のときはデバッグメッセージを [django.request](/ja/2.1/topics/logging/#django-request-logger) ロガーに記録します。

## ミドルウェアを有効にする

ミドルウェア要素をアクティブ化するには、Django の設定内の [`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE) リストに追加してください。

[`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE) では、各ミドルウェア要素は文字列で表されます: ミドルウェアファクトリのクラスや関数名に対する完全な Python パスです。 例えば、以下は [`django-admin startproject`](/ja/2.1/ref/django-admin/#django-admin-startproject) で生成されるデフォルト値です:

```
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',
]
```

Django の導入では、ミドルウェアは必須ではありません — お望みならば [`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE) は空でも構いません — しかし、最低でも [`CommonMiddleware`](/ja/2.1/ref/middleware/#django.middleware.common.CommonMiddleware) を使うことを強くお勧めします。

ミドルウェアは他のミドルウェアに依存するため、[`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE) の順番は重要です。[`AuthenticationMiddleware`](/ja/2.1/ref/middleware/#django.contrib.auth.middleware.AuthenticationMiddleware) はセッション内に認証済みユーザを保持します。したがって、[`SessionMiddleware`](/ja/2.1/ref/middleware/#django.contrib.sessions.middleware.SessionMiddleware) の後に起動する必要があります。Django のミドルウェアクラスの順番については、[Middleware の順序](/ja/2.1/ref/middleware/#middleware-ordering) を参照してください。

## ミドルウェアの順番とレイヤ

ビューを呼び出す前、リクエストの段階で、Django は [`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE) 内で定義された順番で上から下に向かってミドルウェアを適用します。

これはタマネギのように考えることができます: 各ミドルウェアクラスは、タマネギの中心にあるビューをラップする "レイヤ" です。リクエストがタマネギのすべてのレイヤ (つまり中心にあるビューにいたる全ての道) を通過すると (各レイヤーは `get_response` を呼び出してリクエストを次のレイヤに渡します)、レスポンスは各レイヤーを (逆順で) 通過して戻ります。

いずれかのレイヤが短絡し、`get_response` を呼び出さずにレスポンスを返すことを決定した場合、そのレイヤの内側にあるタマネギの (ビューを含む) レイヤはリクエストおよびレスポンスを受け取りません。 レスポンスは、リクエストが通過したのと同じレイヤーを介してのみ返されます。

## 他のミドルウェアのフック

上述した基本的なリクエストやレスポンスのミドルウェアパターンのほかに、3 つの特殊なメソッドをクラスベースのミドルウェアに追加することができます:

### `process_view()`

#### `process_view(request, view_func, view_args, view_kwargs)`

`request` は [`HttpRequest`](/ja/2.1/ref/request-response/#django.http.HttpRequest) クラスのオブジェクトです。`view_func` は、直後に Django が使用する Python の関数です (関数の名前の文字列ではなく、実際の関数オブジェクトです)。`view_args` はビューに渡される位置引数のリスト、`view_kwargs` はビューに渡されるキーワード引数のディクショナリです。`view_args` も `view_kwargs` も、第一引数 (`request`) を含んでいません。

`process_view()` は、Django がビューを呼び出す直前に呼び出されます。

`None` もしくは [`HttpResponse`](/ja/2.1/ref/request-response/#django.http.HttpResponse) オブジェクトを返す必要があります。`None` を返す場合、Django はこのリクエストの処理を続け、他のすべての `process_view()` ミドルウェアを実行し、さらに適切なビューを実行します。[`HttpResponse`](/ja/2.1/ref/request-response/#django.http.HttpResponse) オブジェクトを返す場合、Django はわざわざ適切なビューを呼び出すことはしません; レスポンスミドルウェアを [`HttpResponse`](/ja/2.1/ref/request-response/#django.http.HttpResponse) に適用し、結果を返します。

> **Note**
>
> ビューが実行される、ミドルウェアの内側もしくは `process_view()` 内の [`request.POST`](/ja/2.1/ref/request-response/#django.http.HttpRequest.POST) にアクセスすると、ミドルウェアの後に実行される全てのビューが [リクエストに対するアップロードハンドラを修正する](/ja/2.1/topics/http/file-uploads/#modifying-upload-handlers-on-the-fly) ことができなくなるため、通常は避けられるべきです。
>
> [`CsrfViewMiddleware`](/ja/2.1/ref/middleware/#django.middleware.csrf.CsrfViewMiddleware) クラスだけは例外と考えていいでしょう。というのも、このミドルウェアには、[`csrf_exempt()`](/ja/2.1/ref/csrf/#django.views.decorators.csrf.csrf_exempt) と [`csrf_protect()`](/ja/2.1/ref/csrf/#django.views.decorators.csrf.csrf_protect) というデコレータが用意されていて、このデコレータを使えば、CSRF の検証が必要になったどの時点でも、明示的にビューを制御できるからです。

### `process_exception()`

#### `process_exception(request, exception)`

`request` は [`HttpRequest`](/ja/2.1/ref/request-response/#django.http.HttpRequest) オブジェクトです。`exception` は、ビュー関数から投げられた `Exception` オブジェクトです。

Django calls `process_exception()` when a view raises an exception.
`process_exception()` should return either `None` or an
[`HttpResponse`](/ja/2.1/ref/request-response/#django.http.HttpResponse) object. If it returns an
[`HttpResponse`](/ja/2.1/ref/request-response/#django.http.HttpResponse) object, the template response and response
middleware will be applied and the resulting response returned to the
browser. Otherwise, [default exception handling](/ja/2.1/ref/views/#error-views) kicks in.

Again, middleware are run in reverse order during the response phase, which
includes `process_exception`. If an exception middleware returns a response,
the `process_exception` methods of the middleware classes above that
middleware won't be called at all.

### `process_template_response()`

#### `process_template_response(request, response)`

`request` は [`HttpRequest`](/ja/2.1/ref/request-response/#django.http.HttpRequest) クラスのオブジェクトです。`response` は、Django のビューまたはミドルウェアから返される、[`TemplateResponse`](/ja/2.1/ref/template-response/#django.template.response.TemplateResponse) クラスのオブジェクト (あるいはそれと同等なもの) です。

`process_template_response()` は、レスポンスオブジェクトが `r
ender()` メソッドを持っている場合、つまり、[`TemplateResponse`](/ja/2.1/ref/template-response/#django.template.response.TemplateResponse) クラスのオブジェクト (あるいはそれと同等のもの) である場合に、ビューの実行の直後に呼ばれます。

このメソッドは、`render` メソッドを実装したレスポンスオブジェクトでなければなりません。このメソッド内では、与えられた `response` に対して `response.template_name` や `response.context_data` を修正したり、あるいは、新規に [`TemplateResponse`](/ja/2.1/ref/template-response/#django.template.response.TemplateResponse) クラスのオブジェクト (あるいはそれと同等なもの) を作成したりすることができます。

ただし、レスポンスを自分でレンダリング (render) する必要はありません。なぜなら、レスポンスオブジェクトは、すべてのテンプレートレスポンスミドルウェアが呼び出された後に、自動的にレンダリングされるからです。

レスポンスフェーズでは、ミドルウェアは逆順に呼び出されます。これには、`process_template_response()` も含まれます。

## ストリーミングレスポンス (streaming responses) を扱う

[`HttpResponse`](/ja/2.1/ref/request-response/#django.http.HttpResponse) とは違い、[`StreamingHttpResponse`](/ja/2.1/ref/request-response/#django.http.StreamingHttpResponse) は `content` 属性を持ちません。そのため、ミドルウェアはもはや、すべてのレスポンスが `content` 属性を持っていることを前提にすることができなくなります。したがって、content にアクセスする必要がある場合には、レスポンスオブジェクトがストリーミングレスポンスオブジェクトかどうかをチェックし、その結果によって処理を場合分けしなければなりません。

```
if response.streaming:
    response.streaming_content = wrap_streaming_content(response.streaming_content)
else:
    response.content = alter_content(response.content)
```

> **Note**
>
> `streaming_content` はメモリ上に置けないくらい大きいと想定しておくべきです。レスポンスミドルウェアでは、これを新しいジェネレータでラッピングすることができます。しかし、このジェネレータを処理することがあってはなりません。典型的なラッピング方法は、次のようになります。
>
> ```
> def wrap_streaming_content(content):
>     for chunk in content:
>         yield alter_content(chunk)
> ```

## Exception handling

Django automatically converts exceptions raised by the view or by middleware
into an appropriate HTTP response with an error status code. [Certain
exceptions](/ja/2.1/ref/views/#error-views) are converted to 4xx status codes, while an unknown
exception is converted to a 500 status code.

This conversion takes place before and after each middleware (you can think of
it as the thin film in between each layer of the onion), so that every
middleware can always rely on getting some kind of HTTP response back from
calling its `get_response` callable. Middleware don't need to worry about
wrapping their call to `get_response` in a `try/except` and handling an
exception that might have been raised by a later middleware or the view. Even
if the very next middleware in the chain raises an
[`Http404`](/ja/2.1/topics/http/views/#django.http.Http404) exception, for example, your middleware won't see
that exception; instead it will get an [`HttpResponse`](/ja/2.1/ref/request-response/#django.http.HttpResponse)
object with a [`status_code`](/ja/2.1/ref/request-response/#django.http.HttpResponse.status_code) of 404.

## Django 1.10 以前のスタイルのミドルウェアをアップグレードする

#### `class django.utils.deprecation.MiddlewareMixin`

Django は `django.utils.deprecation.MiddlewareMixin` を提供し、[`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE) と以前の `MIDDLEWARE_CLASSES` 両方に互換性のあるミドルウェアクラスの作成を簡単にしています。Django に含まれる全てのミドルウェアクラスは、両方の設定で互換性があります。

mixin は `__init__()` メソッドを提供しています。これは、省略可能な `get_response` 引数を受け取って `self.get_response` に保持します。

`__call__()` メソッド:

1. (定義されている場合) `self.process_request(request)` を呼び出します。
2. `self.get_response(request)` を呼び出し、後のミドルウェアとビューからレスポンスを得ます。
3. (定義されている場合) `self.process_response(request, response)` を呼び出します。
4. レスポンスを返します。

`MIDDLEWARE_CLASSES` で使われている場合は、`__call__()` メソッドは決して使われません; Django は `process_request()` と `process_response()` を直接呼び出します。

ほとんどの場合、この mixin を継承することで、旧式のミドルウェアと十分な下位互換性を持つ新しいシステムと互換性を持たせることができます。 新しい短絡セマンティクスは無害であり、既存のミドルウェアにとっても有益です。 いくつかのケースでは、ミドルウェアクラスは新しいセマンティクスに調整するためにいくつかの変更を必要とすることがあります。

[`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE) と `MIDDLEWARE_CLASSES` の動作には以下のような違いがあります。

1. Under `MIDDLEWARE_CLASSES`, every middleware will always have its
   `process_response` method called, even if an earlier middleware
   short-circuited by returning a response from its `process_request`
   method. Under [`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE), middleware behaves more like an onion:
   the layers that a response goes through on the way out are the same layers
   that saw the request on the way in. If a middleware short-circuits, only
   that middleware and the ones before it in [`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE) will see the
   response.
2. Under `MIDDLEWARE_CLASSES`, `process_exception` is applied to
   exceptions raised from a middleware `process_request` method. Under
   [`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE), `process_exception` applies only to exceptions
   raised from the view (or from the `render` method of a
   [`TemplateResponse`](/ja/2.1/ref/template-response/#django.template.response.TemplateResponse)). Exceptions raised from
   a middleware are converted to the appropriate HTTP response and then passed
   to the next middleware.
3. Under `MIDDLEWARE_CLASSES`, if a `process_response` method raises
   an exception, the `process_response` methods of all earlier middleware are
   skipped and a `500 Internal Server Error` HTTP response is always
   returned (even if the exception raised was e.g. an
   [`Http404`](/ja/2.1/topics/http/views/#django.http.Http404)). Under [`MIDDLEWARE`](/ja/2.1/ref/settings/#std-setting-MIDDLEWARE), an exception
   raised from a middleware will immediately be converted to the appropriate
   HTTP response, and then the next middleware in line will see that
   response. Middleware are never skipped due to a middleware raising an
   exception.
