# Django 5.0.9.dev20240806133106 ドキュメント

# クラスベースビュー

ビューはリクエストを受けてレスポンスを返す callable です。これは単なる関数以上のものになる可能性があり、Django ではビューとして使用できるいくつかのクラスの例を提供しています。これらのクラスは、継承やミックスインを利用してビューを構造化し、コードを再利用することを可能にします。後ほど説明するタスクのための汎用的なビューもありますが、あなたのユースケースに合った再利用可能なビューの構造を独自に設計したいと思うかもしれません。詳細については、クラスベースのビューの リファレンスドキュメント を参照してくださ

- クラスベースビュー入門
- 組み込みのクラスベースのジェネリックビュー（汎用ビュー）
- クラスベースのビューでフォームを扱う
- クラスベースのビューでミックスイン (mixin) を使用する

## 基本的な例

Django は、さまざまなアプリケーションに広く適用できるベースビュークラスを用意しています。 `View` クラスを継承したすべてのビューは、指定した URL へのビューのリンクや、送り出す HTTP メソッド、その他よく使われる機能をハンドリングします。 `RedirectView` は HTTP リダイレクトを行うビュークラス、 `TemplateView` はベースビューを拡張してテンプレートレンダリングの機能をもたせたビュークラスです。

## URLconfでの使用法

ジェネリックビューを使用する最もダイレクトな方法は、URLconf 内で直接オブジェクトを作成することです。クラスベースビューの属性をいくつか変更するだけなら、 `as_view()` のメソッド呼び出しに渡せばよいのです。

    from django.urls import path
    from django.views.generic import TemplateView

    urlpatterns = [
        path("about/", TemplateView.as_view(template_name="about.html")),
    ]

`as_view()` に渡されたすべての引数は、クラスで設定された属性を上書きします。次の例では `TemplateView` の `template_name` を設定しています。同様の上書きのパターンは、`RedirectView` の `url` 属性でも使えます。

## ジェネリックビューのサブクラス化

次に、ジェネリックビューのもっと強力な使用例として、既存のビューを継承して、新しい値やメソッドを提供するために、 `template_name` などの属性や `get_context_data` などのメソッドをサブクラスで上書きする方法を紹介します。たとえば、1つのテンプレート `about.html` だけを表示するビューを作ることを考えてみてください。Django には、このために利用できるジェネリックビュー `TemplateView` があるので、これをサブクラス化し、テンプレート名を上書きすることで実装できます。

    # some_app/views.py
    from django.views.generic import TemplateView

    class AboutView(TemplateView):
        template_name = "about.html"

あとは、URLconf にこの新しいビューを追加する必要があります。 `TemplateView` は1つのクラスであって、関数ではありません。そのため、指定する URL に対して、代わりに `as_view()` クラスメソッドを設定しています。これによって、クラスベースビューに対する関数ライクな要素を指定できます。

    # urls.py
    from django.urls import path
    from some_app.views import AboutView

    urlpatterns = [
        path("about/", AboutView.as_view()),
    ]

組み込みの汎用ビューの使用方法の詳細については、次のトピック 汎用のクラスベースビュー を参照してください。

### その他の HTTP メソッドをサポートする

誰かが私たちのライブラリに HTTP 経由でアクセスして、ビューを API として使用したいという状況を考えてください。API クライアントはたびたびコネクションを張り、最終訪問日時以降に出版された本のデータをダウンロードするとします。しかし、新しい本の情報が存在しない場合には、データベースから本のデータを取得し、レスポンステキストをレンダリングし、クライアントに送信し返すための CPU タイムとバンド幅は無駄になってしまいます。最新の本が出版された時点で API に問い合わせた方が好ましいかもしれません。

そのために、URLconf 内で、本のリストビューへの URL を次のようにマッピングします。

    from django.urls import path
    from books.views import BookListView

    urlpatterns = [
        path("books/", BookListView.as_view()),
    ]

そして、ビューには次のように書きます。

    from django.http import HttpResponse
    from django.views.generic import ListView
    from books.models import Book

    class BookListView(ListView):
        model = Book

        def head(self, *args, **kwargs):
            last_book = self.get_queryset().latest("publication_date")
            response = HttpResponse(
                # RFC 1123 date format.
                headers={
                    "Last-Modified": last_book.publication_date.strftime(
                        "%a, %d %b %Y %H:%M:%S GMT"
                    )
                },
            )
            return response

ビューが `GET` リクエストからアクセスされた場合、レスポンスにはオブジェクトリストが返されます( `book_list.html` テンプレートを使用しています)。しかし、クライアントがHEADリクエストを発行した場合、レスポンスは空のボディを持ち、 `Last-Modified` ヘッダーは最新の書籍がいつ発行されたかを示します。この情報に基づいて、クライアントは完全なオブジェクトリストをダウンロードするかどうかを判断します。

## 非同期のクラスベース・ビュー

既に示した同期 (`def`) メソッドハンドラと同様に、 `View` サブクラスは `await`: を使用して非同期 (`async def`) メソッドハンドラを定義できます:

    import asyncio
    from django.http import HttpResponse
    from django.views import View

    class AsyncView(View):
        async def get(self, request, *args, **kwargs):
            # Perform io-blocking view logic using await, sleep for example.
            await asyncio.sleep(1)
            return HttpResponse("Hello async world!")

1つのビュークラス内では、すべてのユーザー定義メソッドハンドラは `def` を使用した同期的なものか、 `async def` を使用した非同期的なものでなければなりません。 `def` と `async def` が混在している場合、 `as_view()` で `ImproperlyConfigured` 例外が発生します。

Django は自動的に非同期ビューを検出し、非同期コンテキストで実行します。Django の非同期サポートや、非同期ビューの最適な使い方については、 非同期サポート を参照してください。