.. _topics-http-views:
=============
ビューを書く
=============
:revision-up-to: 8961 (1.0)
ビュー関数、あるいは単に *ビュー* とは、簡単にいえばウェブリクエストを引数
にとり、ウェブレスポンスを返す関数です。レスポンスはウェブページを表す HTML
コンテンツでもよいし、リダイレクトでも、 404 エラーでも、 XML ドキュメント
でも、画像でも、何でもかまいません。ビューの中には、レスポンスを生成する上
で必要なロジックを自由に書けます。ビューのコードは、 Python パス上にあるか
ぎり、どこに置いてもかまいません。他にはなんの制限も「黒魔術」もありません。
とはいえ、この節の例では、 ``mysite`` ディレクトリ下に ``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:
* まず、 ``django.http`` モジュールから ``HttpResponse`` クラスを
import しています。 Python の ``datetime`` ライブラリもロードしておき
ます。
* 次に、 ``current_datetime`` という関数を定義しています。これがビュー
関数です。ビュー関数は第一引数に ``HttpRequest`` オブジェクトを取りま
す。慣習的に、この引数の名前は ``request`` にしています。
ビュー関数はどんな名前でもかまいません。Django にビュー関数として認識
してもらうために、何らかの特殊な命名規則に従う必要はないのです。ここ
では、 ``current_datetime`` という名前を付けて、どんな機能のビューか
分かりやすくしています。
* ビューは、生成したレスポンスコンテンツの入った ``HttpResponse`` オブ
ジェクトを返します。ビュー関数は ``HttpResponse`` オブジェクトを返さ
ねばなりません (例外も返してよいのですが、それについては後で説明しま
す)。
.. admonition:: Django のタイムゾーン設定
Django には :setting:`TIME_ZONE` 設定があり、デフォルト値は
``America/Chicago`` に設定されています。お住まいの地域がここでなければ、
変更しておいてください。
URL をビューにマップする
===========================
このビュー関数は、現在の日付と時刻が入った HTML ページを生成して返します。
何らかの URL でこのビューを表示したければ、 *URLconf* を作成する必要があり
ます。 :ref:`topics-http-urls` の説明を読んでください。
.. _Returning errors:
エラーを返す
============
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
')
ただし、 404 エラーは他の HTTP エラーよりはるかに良く使われるエラーなので、
もっと簡単に扱う方法を提供しています。
.. _The Http404 exception:
Http404 例外
------------
``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:
エラービューのカスタマイズ
==========================
.. _The 404 (page not found) view:
404 (ページが見つかりません) ビュー
------------------------------------
``Http404`` 例外を送出すると、 Django は 404 エラー処理用の特殊なビューをロー
ドします。デフォルトでは、このビューは
``django.views.defaults.page_not_found`` に設定されています。
``django.views.defaults.page_not_found`` は ``404.html`` という名前のテンプ
レートをロードしてレンダします。
このため、テンプレートディレクトリの再上階層に ``404.html`` という名前のテ
ンプレートを作成しておかねばなりません。このテンプレートは全ての 404 エラー
に対して用いられます。
``page_not_found`` ビューは 99% の Web アプリケーションの要求を満たすはずで
すが、 404 ビューを自作したい場合には、URLconf で以下のようにして
``handler404`` を指定します::
handler404 = 'mysite.views.my_custom_404_view'
舞台裏では、 Django は ``handler404`` を介して 404 ビューを捜し出します。デ
フォルトでは、 URLconf の以下の行::
from django.conf.urls.defaults import *
によって、 ``handler404`` が現在のモジュールに取り込まれます。
``django/conf/urls/defaults.py`` を見れば分かりますが、 ``handler404`` のデ
フォルト値は ``'django.views.defaults.page_not_found'`` に設定されています。
404 ビューについて、知っておかねばならないことが 3 つあります:
* 404 ビューは、リクエストされた URL に対して、 Django が URLconf の全
ての正規表現を調べた結果、一致するものをみつけられなかった場合にも呼
び出されます。
* 404 ビューを自作せず、ただデフォルトのビューを使う場合でも、一つだけ
やらねばならないこととして、 ``404.html`` という名前のテンプレートを
作成せねばなりません。このテンプレートはテンプレートディレクトリの最
上階層に配置します。デフォルトの 404 ビューは全ての 404 エラーに対
して同じテンプレートを使います。デフォルトの 404 ビューは、 404 エラー
を引き起こした URL を、``request_path`` という変数としてテンプレート
に渡します。
* 404 ビューに渡されるコンテキストは ``RequestContext`` なので、
テンプレートには ``TEMPLATE_CONTEXT_PROCESSORS`` で追加した変数も
渡ります。
* (settings モジュールで) ``DEBUG`` を ``True`` にすると、 404 ビューは
呼び出されず、代わりにトレースバックが表示されます。
.. _The 500 (server error) view:
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 は ``handler500`` を介して 500 ビューを捜し出します。デ
フォルトでは、 URLconf の以下の行::
from django.conf.urls.defaults import *
によって、 ``handler500`` が現在のモジュールに取り込まれます。
``django/conf/urls/defaults.py`` を見れば分かりますが、 ``handler500`` のデ
フォルト値は ``'django.views.defaults.server_error'`` に設定されています。