.. _topics-http-views: ============= ビューを書く ============= :revision-up-to: 17812 (1.4) ビュー関数、あるいは単に *ビュー* とは、簡単にいえばウェブリクエストを引数 にとり、ウェブレスポンスを返す関数です。レスポンスはウェブページを表す HTML コンテンツでもよいし、リダイレクトでも、 404 エラーでも、 XML ドキュメント でも、画像でも、何でもかまいません。ビューの中には、レスポンスを生成する上 で必要なロジックを自由に書けます。ビューのコードは、 Python パス上にあるか ぎり、どこに置いてもかまいません。他にはなんの制限も「黒魔術」もありません。 慣習では、 プロジェクトディレクトリかアプリケーションディレクトリの下に ``views.py`` という名前のファイルを作成して、そこにビューのコードを置くこと になっています。 簡単なビュー ============= 以下に示すのは、現在の日付や時刻を HTML 形式で返すビューの例です: .. code-block:: python from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = "It is now %s." % now return HttpResponse(html) Let's step through this code one line at a time: * まず、 :mod:`django.http` モジュールから :class:`~django.http.HttpResponse` クラスを import しています。 Python の ``datetime`` ライブラリもロードしておきます。 * 次に、 ``current_datetime`` という関数を定義しています。これがビュー 関数です。ビュー関数は第一引数に :class:`~django.http.HttpRequest` オブジェクトを取ります。慣習的に、この引数の名前は ``request`` にして います。 ビュー関数はどんな名前でもかまいません。Django にビュー関数として認識 してもらうために、何らかの特殊な命名規則に従う必要はないのです。ここ では、 ``current_datetime`` という名前を付けて、どんな機能のビューか 分かりやすくしています。 * ビューは、生成したレスポンスコンテンツの入った :class:`~django.http.HttpResponse` オブジェクトを返します。ビュー関数 は ``HttpResponse`` オブジェクトを返さねばなりません (例外も返してよ いのですが、それについては後で説明します)。 .. admonition:: Django のタイムゾーン設定 Django には :setting:`TIME_ZONE` 設定があり、デフォルト値は ``America/Chicago`` に設定されています。お住まいの地域がここでなければ、 変更しておいてください。 URL をビューにマップする =========================== このビュー関数は、現在の日付と時刻が入った HTML ページを生成して返します。 何らかの URL でこのビューを表示したければ、 *URLconf* を作成する必要があり ます。 :doc:`/topics/http/urls` の説明を読んでください。 エラーを返す ============ Django では、簡単に HTTP エラーコードを返せます。エラー応答は、すでに述べた :class:`HttpResponseNotFound`, :class:`HttpResponseForbidden`, :class:`HttpResponseServerError` といったサブクラスのインスタンスを作成して、 以下の例のように通常の :class:`~django.http.HttpResponse` の代わりに返すだ けです:: def my_view(request): # ... if foo: return HttpResponseNotFound('

Page not found

') else: return HttpResponse('

Page was found

') 全ての HTTP レスポンスコードごとに特別なサブクラスがあるわけではありません。 多くは共通化できるからです。しかし :class:`~django.http.HttpResponse` のドキ ュメントにあるように、 :class:`~django.http.HttpResponse` のコンストラクタに HTTP ステータスコードを渡すことで、好きなステータスコードを返すクラスを作れ ます。例:: def my_view(request): # ... # Return a "created" (201) response code. return HttpResponse(status=201) ただし、 404 エラーは他の HTTP エラーよりはるかに良く使われるエラーなので、 もっと簡単に扱う方法を提供しています。 Http404 例外 ------------ .. class:: django.http.Http404() :class:`~django.http.HttpResponseNotFound`` のようなエラーを返す場合、以下 のように、エラーページの中身になる HTML を指定せねばなりません:: return HttpResponseNotFound('

Page not found

') これはちょっと不便ですね。それに、サイト全体で一貫した 404 エラーページを用 意しておく方が賢明です。そこで、 Django には ``Http404`` 例外があります。 ビュー関数のどこかで ``Http404`` 例外を送出すると、 Django はこのエラーを捕 捉して、サイト標準のエラーページを HTTP エラーコード 404 で返します。 例を示しましょう:: from django.http import Http404 def detail(request, poll_id): try: p = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404 return render_to_response('polls/detail.html', {'poll': p}) ``Http404`` 例外を使うには、 404 エラーの送出時に表示されるテンプレートを作 成しておかねばなりません。このテンプレートの名前は ``404.html`` で、テンプ レートツリーの一番上に配置せねばなりません。 .. _customizing-error-views: エラービューのカスタマイズ ========================== 404 (ページが見つかりません) ビュー ------------------------------------ ``Http404`` 例外を送出すると、 Django は 404 エラー処理用の特殊なビューをロー ドします。デフォルトでは、このビューは ``django.views.defaults.page_not_found`` に設定されています。 ``django.views.defaults.page_not_found`` は ``404.html`` という名前のテンプ レートをロードしてレンダします。 このため、テンプレートディレクトリの再上階層に ``404.html`` という名前のテ ンプレートを作成しておかねばなりません。このテンプレートは全ての 404 エラー に対して用いられます。デフォルトの 404 ビューはテンプレートに ``request_path`` という変数を渡します。これはエラーになった URL です。 ``page_not_found`` ビューは 99% の Web アプリケーションの要求を満たすはずで すが、 404 ビューを自作したい場合には、URLconf で以下のようにして ``handler404`` を指定します:: handler404 = 'mysite.views.my_custom_404_view' 舞台裏では、 Django はルート URLconf の ``handler404`` を介して 404 ビューを 捜し出します。定義がなければ ``django.views.defaults.page_not_found`` にフォ ールバックします。 404 ビューについて、知っておかねばならないことが 4 つあります: * 404 ビューは、リクエストされた URL に対して、 Django が URLconf の全 ての正規表現を調べた結果、一致するものをみつけられなかった場合にも呼 び出されます。 * 404 ビューを自作せず、ただデフォルトのビューを使う場合でも、一つだけ やらねばならないこととして、 ``404.html`` という名前のテンプレートを 作成せねばなりません。 * 404 ビューに渡されるコンテキストは :class:`django.template.RequestContext` なので、テンプレートには ``TEMPLATE_CONTEXT_PROCESSORS`` で追加した変数も 渡ります。 (例えば ``MEDIA_URL``) * (settings モジュールで) :setting:`DEBUG` を ``True`` にすると、 404 ビューは 呼び出されず、代わりにトレースバックが表示されます。 500 (サーバエラー) ビュー --------------------------- 404 エラーと同様に、 Django はビューのコード上で実行時エラーに遭遇した場合 の挙動も特別扱いしています。ビューを実行した結果、例外が送出されると、 Django はデフォルトで ``django.views.defaults.server_error`` というビューを 呼び出します。このビューは ``500.html`` というテンプレートをロードしてレン ダします。 このため、テンプレートディレクトリの再上階層に ``500.html`` という名前のテ ンプレートを作成しておかねばなりません。このテンプレートは全ての 500 エラー に対して用いられます。デフォルトの 500 ビューはテンプレートに一切変数を渡さ ず、空の ``Context`` インスタンスを渡してレンダリングを実行しますが、これは さらなるエラーが発生するのを防ぐためです。 ``server_error`` ビューは 99% の Web アプリケーションの要求を満たすはずです が、 500 ビューを自作したい場合には、URLconf で以下のようにして ``handler500`` を指定します:: handler500 = 'mysite.views.my_custom_error_view' 舞台裏では、 Django はルート URLconf の ``handler500`` を介して 500 ビューを 捜し出します。何も定義していなければ、 ``django.views.defaults.server_error`` にフォールバックします。 500 ビューについて、知っておかねばならないことが 2 つあります: * 500 ビューを自作せず、ただデフォルトのビューを使う場合でも、一つだけ やらねばならないこととして、 ``500.html`` という名前のテンプレートを 作成せねばなりません。 * (settings モジュールで) :setting:`DEBUG` を ``True`` にすると、 500 ビューは 呼び出されず、代わりにトレースバックが表示されます。 .. _http_forbidden_view: 403 (閲覧が禁止されています) ビュー ----------------------------------- .. versionadded:: 1.4 404 ビュー、 500 ビューと同じスタイルで、 Django は 403 Forbidden エラーを 処理するためのビューを持っています。ビューが 403 例外を起こしたら、 Django はデフォルトでは ``django.views.defaults.permission_denied`` ビューを呼びま す。 このビューは ``403.html`` テンプレートを最上階層のテンプレートディレクトリ からロードし、レンダします。ファイルがない場合、 :rfc:`2616` (HTTP 1.1 仕様) により "403 Forbidden" テキストを返します。 404 や 500 ビューと同じように、 ``handler403`` を URLconf に設定することで ``django.views.defaults.permission_denied`` をオーバーライドできます:: handler403 = 'mysite.views.my_custom_permission_denied_view'