クラスベースビュー

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

基本的な例

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() に渡されたすべての引数は、クラスで設定された属性を上書きします。次の例では TemplateViewtemplate_name を設定しています。同様の上書きのパターンは、RedirectViewurl 属性でも使えます。

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

2つ目の、より強力な汎用ビューの使用方法は、既存のビューを継承し、サブクラス内の属性( template_name``など)やメソッド( ``get_context_data``など)をオーバーライドして、新しい値やメソッドを提供することです。例えば、``about.html. というテンプレートを表示するだけのビューを考えてみましょう。Django にはこれを行うための汎用ビュー、TemplateView があるので、それをサブクラス化してテンプレート名をオーバーライドすることができます:

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

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

次に、この新しいビューをURLconfに追加する必要があります。TemplateView は関数ではなくクラスなので、代わりに as_view() クラスメソッドを URL に指定します。

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

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

組み込みのジェネリックビューの使用方法の詳細については、次のトピック generic class-based views を参照してください。

その他の 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 ヘッダーは最新の書籍がいつ発行されたかを示します。この情報に基づいて、クライアントは完全なオブジェクトリストをダウンロードするかどうかを判断します。

Asynchronous class-based views

New in Django 4.1.

As well as the synchronous (def) method handlers already shown, View subclasses may define asynchronous (async def) method handlers to leverage asynchronous code using await:

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!")

Within a single view-class, all user-defined method handlers must be either synchronous, using def, or all asynchronous, using async def. An ImproperlyConfigured exception will be raised in as_view() if def and async def declarations are mixed.

Django will automatically detect asynchronous views and run them in an asynchronous context. You can read more about Django's asynchronous support, and how to best use async views, in 非同期サポート.

Back to Top