Source

djangobook-cn / docs / _build / pickle / _sources / 2.0 / chapter03.txt

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
.. _2.0-chapter03:

======================
第3章: View と URLconf
======================

前章で、私たちは Django プロジェクトを作成し、
Django 開発用サーバを起動する方法を解説しました。
この章では、Django で動的なWebページを作成するための基本を学びます。

初めての Django で動作するページ: Hello World
---------------------------------------------

私たちの最初の目標として、
決まり文句 "Hello World" を出力するWebページを作ってみましょう。

もしあなたが、Webフレームワークを使わずに、
単純に "Hello World" と出力するだけのWebページを作成した場合は、
単純に "Hello World" と書いたテキストファイルを `hello.html` 
等の名前で保存し、
Webサーバ内のディレクトリーにアップロードするだけです。

このプロセスで、あなたはWebページに関する2つの重要な情報を
決定していることに注目してください。
その内容("Hello World"という文字列)と、
そのURL( `http://www.example.com/hello.html
<http://www.example.com/hello.html>`_ もしくは、
あなたがサブディレクトリーにアップロードしたのであれば、
おそらく `http://www.example.com/files/hello.html
<http://www.example.com/files/hello.html>`_ )です。

Django では、同様に2つの情報を指定しますが、
指定方法が異なっています。
ページの内容は *View 関数* が生成し、
URL は *URLconfs* で指定します。
最初に、私たちの "Hello World" View 関数を書いてみましょう。

初めての View
~~~~~~~~~~~~~

前章で、 `django-admin.py startproject` により作成した `mysite` ディレクトリー内に、 
`views.py` という名前のファイルを作成してください。
この Python モジュールは、この章の View に該当しています。 
`views.py` という名前に特別な意味はないので注意してください - 
もう少し後で解説しますが、Django にファイルの名前は関係ありません。
しかし、これは `views.py` と呼ぶのが慣習であり、
あなたのコードを他の開発者が読みやすいため、良い考えです。

私たちの "Hello World" View 関数は非常に単純です。
ここに、 
`import` 宣言を含む全ての関数があるので、
あなたはこれを `views.py` に入力する必要があります。

.. sourcecode:: python
    
    from django.http import HttpResponse

    def hello(request):
        return HttpResponse("Hello world")

このコードの各行ごとに、そのステップを解説します。

* 最初の行で、私たちは `django.http` モジュール内にある 
  `HttpResponse` クラスをインポートしています。
  私たちはこのクラスをコード内で利用するので、
  それをインポートする必要があります。

* 次の行で、 `hello` という名前の関数を定義しています - View 関数

  各 View 関数は、少なくとも1つ以上の引数を受け取り、
  慣習では `request` という名前が使われています。
  これは、この View を呼び出した Web リクエストに関する情報を含んでおり、
  それは `django.http.HttpRequest` クラスのインスタンスです。
  この例では、私たちは `request` に対して何も操作していませんが、
  それは View 関数の最初の引数である必要があります。

  View 関数の名前に特別な意味はないので注意してください; 
  それを Django に通知するために特定の規則に基づく名前を付ける必要はありません。
  私たちは、View の目的を明確に示すために `hello` という名前にしていますが、
  それは、 `hello_wonderful_beautiful_world` 、または他の名前を付けることもできます。
  次の "はじめての URLconf" セクションでは、
  Django がどのようにしてこの機能を見つけるかに光を当てます。

* 最後の行は、この関数の(1行の単純な)処理です; 
  それは単に "Hello World" という文字列を引数とした、 `HttpResponse` 
  オブジェクトを返すだけです。

主なレッスンは以下の通りです:
View はただの Python 関数であり、
最初の引数として、 `HttpRequest` を受け取り、 
`HttpResponse` インスタンスを返します。
Django の View は、Python の関数であるため、
2点に注意する必要があります。
(これについては、例外として後ほど解説します。)

初めての URLconf
~~~~~~~~~~~~~~~~

もしこの時点で、あなたが再び `python manage.py runserver` を実行しても、
私たちの "Hello World" というメッセージはどこにも表示されず、
まだ "Welcome to Django" というメッセージが表示されます。
なぜなら、私たちの `mysite` プロジェクトが、
まだ `hello` View を知らないからです。
私たちは、 Django に対し、
特定の URL で、どの View を呼び出すかを明確に指定する必要があります。
(上記の、静的な HTML ファイルを公開する例でいうところの、
HTMLの作成を終え、まだディレクトリーにアップロードされていない状態と類比しています。)
Django で、特定の URL に View をフックするためには、URLconf を利用します。

URLconf は、あなたの Django ベースの Web サイトの目次のようなものです。
その基本動作は、URL パターンと、
そのURL パターンで呼び出される View 関数をマッピングします。
それはあなたが、
「この URL はこの関数を呼ぶ、その URL はその関数を呼ぶ」という風に Django に伝えます。
例えば、
「誰かが URL `/foo/` を表示したら、 
Python モジュール `views.py` の `foo_view()` という View 関数を呼ぶ」という風に伝えます。

あなたが、前章で `django-admin.py startproject` を実行した時に、
このスクリプトが自動的にあなたの URLconf を作成しました: 
`urls.py` ファイル。
デフォルトでは、このようになっているでしょう。

.. sourcecode:: python

    from django.conf.urls.defaults import *

    # Uncomment the next two lines to enable the admin:
    # from django.contrib import admin
    # admin.autodiscover()

    urlpatterns = patterns('',
        # Example:
        # (r'^mysite/', include('mysite.foo.urls')),

        # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
        # to INSTALLED_APPS to enable admin documentation:
        # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

        # Uncomment the next line to enable the admin:
        # (r'^admin/', include(admin.site.urls)),
    )

デフォルトの URLconf には、
一般的に使われるいくつかの Django 機能がコメントアウトされているので、
その機能の起動はとても簡単で、該当の行をコメントアウトするだけです。
コメントアウトされているコードを除くと、
URLconf に必要不可欠な部分はここです:

.. sourcecode:: python

    from django.conf.urls.defaults import *

    urlpatterns = patterns('',
    )

このコードの各行ごとに、そのステップを解説します。

* 最初の行は、Django の URLconf 基盤である 
  `django.conf.urls.defaults` 内のすべてのモジュールをインポートしています。
  これには、 `patterns` という名前の関数が含まれています。

* 次の行は、 `patterns` 関数で、
  その戻り値を `urlpatterns` という変数に格納しています。 
  `patterns` 関数はひとつだけ引数を受け取っています - 
  例では空文字です。
  (この文字列は、View 関数にプレフィクス (prefix) 引数を渡すために用いますが、
  私たちは今のところこの上級テクニックの解説はしません。)

ここで注意すべき重要なことは、
Django は、あなたの URLconf モジュールから 
`urlpatterns` 変数を探すということです。
この変数は、URL と、
その URL から呼び出すコード(例えば View 関数)のマッピングを定義します。
デフォルトでは、私たちが見たとおり、URLconf は空です - 
あなたの Django アプリケーションはまっさらの状態(Blank Slate)です。
(脚注として、この状態は前章にあるように "Welcome to Django" ページを表示します。
あなたの URLconf が空の場合、
Django はあなたが新しいプロジェクトを始めたばかりと仮定し、
そのメッセージを表示します。)

URLconf に、URL と View 関数を追加するには、
URL パターンから View 関数へマップする Python のタプルを追加します。
私たちの `hello` View を呼び出すためには以下のようにします:

.. sourcecode:: python

    from django.conf.urls.defaults import *
    from mysite.views import hello

    urlpatterns = patterns('',
        ('^hello/$', hello),
    )

(私たちは、コードを簡略化するために、
コメントアウトされているコードを省いています。
もしあなたが、それらの行を残しておきたいのであれば、
残しておいても構いません。)

私たちはここで2箇所を変更しました。

* 最初に、私たちは `mysite/views.py` モジュールから、 
  `hello` View をインポートするために、
  Python のインポート構文で、 `mysite.views` をインポートしました。
  (これは、 `mysite/views.py` があなたの Python パス上にあると仮定しています。
  詳細は下記の *あなたの Python パス* を参照してください。)

* 次に、私たちは `urlpatterns` に、 `('^hello/$', hello)` を追加しました。
  この行は、 *URLpattern* と呼ばれています。
  それは、最初の要素がパターンマッチ用の文字列(正規表現など)で、
  次の要素がそのパターンが利用する View 関数である Python タプルです。
  簡単に言うと、私たちは、 `hello` という URL へのどんなリクエストでも、
  `hello` View 関数を呼び出すように Django に指定しました。

.. admonition:: あなたの Python パス

    あなたが Python の `import` 構文を利用する際に Python が見るのは、
    あなたの *Python パス* は、あなたのシステムディレクトリーの一覧です。

    例えば、あなたの Python パスが、 
    `['', '/usr/lib/python2.4/site-packages', '/home/username/djcode']` 
    だったとします。
    もしあなたが、 `from foo import bar` という Python 構文を発行した場合は、
    Python は、カレントディレクトリー(この構文を発行したディレクトリー)内の `foo.py` を探します。
    (Python パスの最初の要素である空文字 `''` は、"カレントディレクトリー"を意味しています。)
    もしそのファイルが見つからない場合、
    Pythonは、 `/usr/lib/python2.4/site-packages/foo.py` を探します。
    そのファイルが見つからない場合は、 `/home/username/djcode/foo.py` を探します。
    最後に、そのファイルを見つけられなかった場合は、 
    `ImportError` を発生させます。

    もし、あなたが自身の Python パスを見てみたいのであれば、
    Python のインタラクティブシェルを起動し、以下を入力してください。

    .. sourcecode:: python

        >>> import sys
        >>> print sys.path

    通常、あなたは Python パスの設定について心配する必要はありません - 
    Python や Django は、その内部で自動的にそれを解決しています。
    (Python パスの設定は、 `manage.py` スクリプトの仕事の一つです。)

この URLpattern 構文をすぐに理解できるように、
これについてディスカッションしてみましょう。
私たちは `/hello/` という URL にマッチさせたいのですが、
パターンがそれとは異なるように見えるかもしれません。
それには以下のような理由があります:

* Djangoは、URLpatterns をチェックする前に、
  すべての URL から先頭のスラッシュを削除します。
  これは、私たちの URLpattern が `/hello/` の先頭のスラッシュを含まないことを意味しています。
  (これは、最初戸惑うかもしれませんが、この要求は物事を単純化します - 
  第8章で解説しますが、URLconfs に、他の URLconfs をインクルードする場合など。)

* パターンは、キャレット記号( `^` )と、ドル記号( `$` )を含んでいます。
  これは特別な意味を持つ正規表現の文字です。
  キャレット記号は「文字列の開始指定にマッチするパターン」を意味しており、
  またドル記号は「文字列の終了指定にマッチするパターン」を意味しています。

  この概念を例によって解説します。
  もし私たちが、仮にパターン `'^hello/'` (ドル記号で終わっていない)を利用した場合、
  `/hello/` だけでなく、 `/hello/foo` や `/hello/bar` のような 
  URLが `/hello/` から始まるすべての URL にマッチしてしまいます。
  同様に、私たちがキャレット記号を削除 (例えば `'hello/$'` )した場合、
  Django は、 `foo/bar/hello/` のような 
  URLが `/hello/` で終わるすべての URL にマッチさせます。
  私たちがキャレット記号やドル記号を使わず、単純に `hello/` とした場合、 
  `foo/hello/bar/` のような 
  URLに `hello/` が含まれるすべての URL にマッチしてしまいます。
  このように、URL `/hello/` だけにマッチすることを保証するために、
  私たちはキャレット記号とドル記号を使います - 
  それ以上でも以下でもありません。

  多くの URLpatterns は、キャレット記号で始まり、ドル記号で終わりますが、
  より詳細なマッチを実現するために素敵な柔軟性を持っています。

  あなたは、誰かが `/hello` (スラッシュなし)でリクエストした場合について、
  疑問に思うかもしれません。
  私たちの URLpatterns にはスラッシュが指定されているので、
  その URL にはマッチしません。
  しかし、デフォルトで、URLpatterns にマッチせず、
  スラッシュで終わっていないすべてのリクエストは、
  スラッシュ付きの同じ URL へリダイレクトされます。
  (これは、Django 設定の `APPEND_SLASH` 設定により管理されており、
  「付録 E」で解説します。)

  もしあなたが、全ての URL がスラッシュで終わる形式が好きなのであれば
  (Django 開発者が好きかどうか)、
  すべての各 URLpattern にスラッシュを追加し、 
  `APPEND_SLASH` の設定を `true` のままにしてください。
  もしあなたが、スラッシュで終わらない URL 形式が好きなのであれば、
  もしくは各 URL 毎にそれを決めたいのであれば、
  `APPEND_SLASH` を `false` に設定して、
  あなたの URLpattern の適切な箇所にスラッシュを追加してください。

この URLconf について他に注目すべきことは、 
`hello` View 関数がオブジェクトのようであり関数を呼び出していないことです。
これは Python の(そしてその他の動的言語の)主要な機能です。

関数は第一級オブジェクト(ファーストクラスオブジェクト: first-class object)であり、
それはあなたが関数を他の変数と同様に取り扱えることを意味しています。
素晴らしいと思いませんか?

URLconf の変更をテストするために、
第2章で実行したように 
`python manage.py runserver` コマンドを実行し、
Django 開発用サーバを起動してください。

(もしあなたがそれを起動したままにしておいても大丈夫です。
開発用サーバはあなたの Python コードの変更箇所を自動的に感知し、
必要に応じてリロードするので、
あなたは変更毎にサーバを再起動する必要ありません。)
サーバは `http://127.0.0.1:8000/` のアドレスで起動されているので、
Web ブラウザを開き `http://127.0.0.1:8000/hello/` を参照してください。

あなたは "Hello World" という文字を確認できるでしょう - 
あなたの Django View が出力した文字列。

おめでとうございます!
あなたは最初の Django で動作するページを完成させました。

.. admonition:: 正規表現

    正規表現(以下 *regex* )は、
    文字列のパターンを指定するための簡潔な方法です。
    Django の URLconfs は URL の強力なマッチ処理のために
    任意の regex を利用できますが、
    恐らくあなたが利用する regex のシンボルは2~3個でしょう。
    一般的なシンボルは以下の通りです。

    +--------------+--------------------------------------------------+
    | シンボル     | マッチ                                           |
    +==============+==================================================+
    | `.` (ドット) | 任意の文字                                       |
    +--------------+--------------------------------------------------+
    | `\d`         | 任意の数値                                       |
    +--------------+--------------------------------------------------+
    | `[A-Z]`      | A~Z(大文字)の任意の文字                       |
    +--------------+--------------------------------------------------+
    | `[a-z]`      | a~z(小文字)の任意の文字                       |
    +--------------+--------------------------------------------------+
    | `[A-Za-z]`   | A~z(大文字小文字を含む)の任意の文字           |
    +--------------+--------------------------------------------------+
    | `+`          | 直前の表現が 1 (個) 以上                         |
    +--------------+--------------------------------------------------+
    | `[^/]+`      | スラッシュを含まない文字列                       |
    +--------------+--------------------------------------------------+
    | `?`          | 直前の表現が 0 (個)、または1個                   |
    +--------------+--------------------------------------------------+
    | `*`          | 直前の表現が 0 (個)以上                          |
    |              | (例えば `d*` はゼロ、または複数桁の数値にマッチ) |
    +--------------+--------------------------------------------------+
    | `{1,3}`      | 直前の表現が 1~3 (個) まで                      |
    |              | (例えば `d{1,3}` は 1、2、3 にマッチ)            |
    +--------------+--------------------------------------------------+

    正規表現に関する詳細については、 `http://www.djangoproject.com/r/python/re-module/
    <http://www.djangoproject.com/r/python/re-module/>`_ を参照してください。
    日本語ドキュメントとしては、 `http://www.python.jp/doc/release/lib/module-re.html
    <http://www.python.jp/doc/release/lib/module-re.html>`_ が参考になります。

早わかり 404 エラー
~~~~~~~~~~~~~~~~~~~

この時点で、私たちの URLconf は、ひとつの URLpattern だけを定義しています: 
それは URL `/hello/` へのリクエストを処理するものです。
もしあなたが、この URL ではない URL に対してリクエストをしたらどうなるでしょうか?

確認のために、
Django 開発用サーバを起動し、 
`http://127.0.0.1:8000/goodbye/` 、
`http://127.0.0.1:8000/hello/subdirectory/` 、
`http://127.0.0.1:8000/` 
(サイトの "ルート")のようなページを
表示してください。

あなたは、 "Page not found" というメッセージ(「図3-2」を参照)と遭遇します。

.. figure:: ../_static/2.0/chapter03/404.png
   :alt: Django の 404 ページのスクリーンショット
   :align: center

   図3-2 Django の 404 ページ

このページのユーティリティは、
ただの基本的な 404 エラーメッセージではありません。
それは、URLconf 内のすべてのパターンと、
Django が使っている URLconf を正確にあなたに伝えます。
その情報から、
あなたはリクエストされた URL が、
なぜ 404 を返したかを見分けることができます。

当然、これは Web 開発者のあなただけが知りうる機密情報です。
もし、これが商用サイトであり、インターネット上にデプロイしているのであれば、
あなたはその情報を公開したくないと思うでしょう。
それは、あなたの Django プロジェクトがデバッグモードで起動されているため、
この "Page not found" ページが表示されているだけです。
私たちは、後でデバッグモードを無効化する方法について解説します。
今のところ、あなたが最初に Django プロジェクトを作成した時は、
それがデバッグモードになっていることを覚えておいてください。
また、プロジェクトがデバッグモードでない場合は、
異なる 404 応答を Django が返すことを覚えておいてください。

早わかり サイトルート
~~~~~~~~~~~~~~~~~~~~~

最後のセクションで解説したように、
あなたがサイトのルートを表示すると、
あなたは 404 エラーメッセージに遭遇します - `http://127.0.0.1:8000/` 。
Django は魔法を使ってサイトルートに何かを追加したりはしません: 
その URL が(どんな場合においても)特別扱いされるわけではありません。
それは、あなたの URLconf 内の他のエントリーと同様に、
それを割り当てるかどうかはあなた次第です。

しかし、サイトルートにマッチする URLpattern は直感的ではないので、
それに言及する価値はあります。
あなたがサイトルートにマッチする View を用意する方法は、
空文字にマッチする `'^$'` を利用してください。

例は以下の通りです。

.. sourcecode:: python

    urlpatterns = patterns('',
        ('^$', my_homepage_view),
        # ...
    )