ビューの記述—Djangoドキュメント

提供:Dev Guides
< DjangoDjango/docs/3.2.x/topics/http/views
移動先:案内検索

ビューを書く

ビュー関数、または略して view は、Web要求を受け取り、Web応答を返すPython関数です。 この応答は、WebページのHTMLコンテンツ、リダイレクト、404エラー、XMLドキュメント、または画像の場合があります。 . . または何か、本当に。 ビュー自体には、その応答を返すために必要な任意のロジックが含まれています。 このコードは、Pythonパス上にある限り、どこにでも配置できます。 他の要件はありません。いわば「魔法」はありません。 コードをどこかに配置するために、慣例では、プロジェクトまたはアプリケーションディレクトリに配置されたviews.pyというファイルにビューを配置します。

シンプルなビュー

これは、現在の日付と時刻をHTMLドキュメントとして返すビューです。

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

このコードを一度に1行ずつ見ていきましょう。

  • まず、Pythonのdatetimeライブラリとともに、 django.http モジュールからクラス HttpResponse をインポートします。

  • 次に、current_datetimeという関数を定義します。 これが表示機能です。 各ビュー関数は、最初のパラメーターとして HttpRequest オブジェクトを取ります。これは通常、requestという名前です。

    ビュー関数の名前は重要ではないことに注意してください。 Djangoがそれを認識するために、特定の方法で名前を付ける必要はありません。 ここではcurrent_datetimeと呼んでいます。これは、その名前がその機能を明確に示しているためです。

  • ビューは、生成された応答を含む HttpResponse オブジェクトを返します。 各ビュー関数は、 HttpResponse オブジェクトを返す役割を果たします。 (例外はありますが、後で説明します。)

Djangoのタイムゾーン

Djangoには、デフォルトでAmerica/Chicagoに設定されている:setting: `TIME_ZONE` 設定が含まれています。 これはおそらくあなたが住んでいる場所ではないので、設定ファイルで変更することをお勧めします。


URLをビューにマッピングする

したがって、要約すると、このビュー関数は現在の日付と時刻を含むHTMLページを返します。 このビューを特定のURLで表示するには、 URLconf を作成する必要があります。 手順については、 URLディスパッチャーを参照してください。


エラーを返す

Djangoは、HTTPエラーコードを返すためのヘルプを提供します。 200以外の多くの一般的なHTTPステータスコード(「OK」を意味する)には、 HttpResponse のサブクラスがあります。 使用可能なサブクラスの完全なリストは、 request / response のドキュメントにあります。 エラーを示すために、通常の HttpResponse の代わりに、これらのサブクラスの1つのインスタンスを返します。 例えば:

from django.http import HttpResponse, HttpResponseNotFound

def my_view(request):
    # ...
    if foo:
        return HttpResponseNotFound('<h1>Page not found</h1>')
    else:
        return HttpResponse('<h1>Page was found</h1>')

それらの多くはそれほど一般的ではないため、考えられるすべてのHTTP応答コードに特化したサブクラスはありません。 ただし、 HttpResponse のドキュメントに記載されているように、HTTPステータスコードを HttpResponse のコンストラクターに渡して、任意のステータスコードの戻りクラスを作成することもできます。 例えば:

from django.http import HttpResponse

def my_view(request):
    # ...

    # Return a "created" (201) response code.
    return HttpResponse(status=201)

404エラーは最も一般的なHTTPエラーであるため、これらのエラーを処理する簡単な方法があります。

Http404例外

class django.http.Http404

HttpResponseNotFound などのエラーを返す場合は、結果のエラーページのHTMLを定義する必要があります。

return HttpResponseNotFound('<h1>Page not found</h1>')

便宜上、またサイト全体で一貫した404エラーページを用意することをお勧めするため、DjangoはHttp404例外を提供します。 ビュー関数の任意の時点でHttp404を上げると、Djangoはそれをキャッチし、HTTPエラーコード404とともにアプリケーションの標準エラーページを返します。

使用例:

from django.http import Http404
from django.shortcuts import render
from polls.models import Poll

def detail(request, poll_id):
    try:
        p = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404("Poll does not exist")
    return render(request, 'polls/detail.html', {'poll': p})

Djangoが404を返したときにカスタマイズされたHTMLを表示するには、404.htmlという名前のHTMLテンプレートを作成し、テンプレートツリーの最上位に配置します。 このテンプレートは、:setting: `DEBUG`Falseに設定されている場合に提供されます。

:setting: `DEBUG`Trueの場合、Http404にメッセージを送信すると、標準の404デバッグテンプレートに表示されます。 これらのメッセージはデバッグ目的で使用してください。 これらは通常、プロダクション404テンプレートでの使用には適していません。


エラービューのカスタマイズ

DjangoのデフォルトのエラービューはほとんどのWebアプリケーションで十分ですが、カスタム動作が必要な場合は簡単に上書きできます。 以下のURLconfでハンドラーを指定します(他の場所にハンドラーを設定しても効果はありません)。

page_not_found()ビューは、 handler404 によってオーバーライドされます。

handler404 = 'mysite.views.my_custom_page_not_found_view'

server_error()ビューは、 handler500 によってオーバーライドされます。

handler500 = 'mysite.views.my_custom_error_view'

permit_denied()ビューは、 handler403 によってオーバーライドされます。

handler403 = 'mysite.views.my_custom_permission_denied_view'

bad_request()ビューは、 handler400 によってオーバーライドされます。

handler400 = 'mysite.views.my_custom_bad_request_view'

も参照してください

:setting: `CSRF_FAILURE_VIEW` 設定を使用して、CSRFエラービューを上書きします。


カスタムエラービューのテスト

カスタムエラーハンドラの応答をテストするには、テストビューで適切な例外を発生させます。 例えば:

from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.test import SimpleTestCase, override_settings
from django.urls import path


def response_error_handler(request, exception=None):
    return HttpResponse('Error handler content', status=403)


def permission_denied_view(request):
    raise PermissionDenied


urlpatterns = [
    path('403/', permission_denied_view),
]

handler403 = response_error_handler


# ROOT_URLCONF must specify the module that contains handler403 = ...
@override_settings(ROOT_URLCONF=__name__)
class CustomErrorHandlerTests(SimpleTestCase):

    def test_handler_renders_template_response(self):
        response = self.client.get('/403/')
        # Make assertions on the response here. For example:
        self.assertContains(response, 'Error handler content', status_code=403)

非同期ビュー

バージョン3.1の新機能。


ビューは同期関数であるだけでなく、非同期(「非同期」)関数でもあり、通常はPythonのasync def構文を使用して定義されます。 Djangoはこれらを自動的に検出し、非同期コンテキストで実行します。 ただし、パフォーマンスを向上させるには、ASGIに基づく非同期サーバーを使用する必要があります。

非同期ビューの例を次に示します。

import datetime
from django.http import HttpResponse

async def current_datetime(request):
    now = datetime.datetime.now()
    html = '<html><body>It is now %s.</body></html>' % now
    return HttpResponse(html)

非同期サポートで、Djangoの非同期サポートと非同期ビューの最適な使用方法の詳細を読むことができます。