Django – DTL – URL

概要

urls.pyでURLパターンからビューへのルーティングを指定しただけの場合、テンプレートでそのルーティングを使うにはURLを直書きしなければならない。

これに対して、urls.pyのURLパターンを任意に変更しても影響が及ばないようにするには、DTLのurlタグを使う。

URLハードコーティングの場合

たとえばmyappアプリケーションのmainページからsubページへのリンクを貼りたいとする。

アプリケーションのurls.pyは以下のようになっているとする。

ルーティングされたビュー関数が以下のように書かれているとする。

レンダリングされるテンプレートでURLをハードコーティングした場合は以下のようになる。

main.html

sub.html

このときのURL指定と各ページの対応は以下のとおり。

  • [DOMAIN]/myapp/ → views.main → main.html
  • [DOMAIN]/myapp/sub → views.sub → sub.html

URLハードコーティングの問題

urls.py中のpath関数のURLのパターンを任意に変化させると、各テンプレート中のURLを全て見直さなければならない。これの影響を及ぼさせないようにしたい。

urls.pyでのname指定

urls.py中、抽象化したいpath関数にname引数を追加する。この場合はsubページへのpath関数を以下のように変更。

そして、subページへのURLの代わりにDTLのurlタグを使い、その引数にurls.pynameで指定した値を与える。

アプリケーションを指定する場合

異なるアプリケーションでnameに指定したい値が重複する場合、[app_name]:[path_name]で指定できるようにする。

path()関数でnameを指定する際、urls.pyの冒頭でapp_name変数にアプリケーション名の文字列を指定しておく。

そして、DTLのurlタグの引数にapp_nameで指定した値を加える。

まとめ

グローバルなパス名の場合

  1. urls.pypath関数にname引数でパス名を指定
  2. URLの代わりに{% url 'パス名' %}を指定

アプリケーションローカルなパス名の場合

  1. urls.pypath関数にname引数でパス名を指定
  2. urls.pyの冒頭でapp_name='アプリケーション名'を記述
  3. URLの代わりに{% url 'アプリケーション名:パス名' %}を指定

 

Django – クラスベースビューの基本

概要

Djangoのビューを実装するのに、関数で書く方法と、Viewクラスやその派生クラスを継承して必要なメソッドをオーバーライドする方法がある。

Djangoのオーソドックスな書き方ではクラスベースビューのListViewなどを利用し、コード量を減らすことが推奨されている。

ここでは関数による方法とViewクラスの継承クラスによる方法の2つを比較する。

基本形

テンプレートの準備

ビューからパラメーターを受け取り、単にそれを表示するテンプレートを準備する。ここではviewtestというアプリケーションを想定し、準備するテンプレートファイルはindex.htmlとする。

関数によるビューの実装

views.pyの記述

アプリケーションディレクトリー下のviews.pyファイルに、indexビューを関数で定義する。ビューではテンプレートに渡すパラメーターを文字列'Hello!'としている。

urls.pyの記述

アプリケーションのサブディレクトリーfunctionから、同じアプリケーションのindexビューへのルーティングを定義する。この例の場合localhost:8000/viewtest/functionのようにURLを指定し、ブラウザーでアクセスすることになる。

ここでサーバー起動状態でブラウザーに先のURLを指定すると、ブラウザーに以下のように表示される。

関数ビューの場合、GETを含むリクエストに対してurls.pyに従ってビューが呼び出され、その内容が実行される。

クラスベースビューによる実装

関数によるビューと同じ処理をクラスベースのビューで実装してみる。ここでは比較のために、関数ビューのコードを残してクラスベースビューのコードを追加していく。

views.pyの記述

クラスベースのビューは、Viewクラスやその派生クラス(ListViewなど)を継承し、getpostなどのリクエストに対応したメソッドを記述する。ここではGETリクエストにのみ反応させるため、getメソッドを実装している。

Viewクラスではgetメソッドは定義されていないが、Viewの派生クラスでGETメソッドでのリクエストがあるとViewクラスのhandlerが実行され、View.get()が実行される。そして派生クラスでget()を定義しているとこれがオーバーライドされたメソッドとして実行される。

参考:Django ViewではHttpメソッド名の関数を定義することができる

urls.pyの記述

クラスベースビューによるメソッドが呼び出されるようにアプリケーションのurls.pypath関数を追加する。

関数ベースの場合はpath関数の第2引数に関数表現のビューモジュールを指定したが、クラスベースの場合はIndexViewの親クラスViewas_view()メソッドを指定している。as_view()メソッドは内部関数view()を通してdispatchメソッドを返すので、結局パスが解決されるとdispatchメソッドが呼び出されることになる。

ここでサーバー起動状態でlocalhost:8000/viewtest/classなどとURLを指定すると、ブラウザーに以下のように表示される。

URLパラメーターを含む場合

関数によるビューの実装

urls.pyの記述

URLパラメーターを含む場合、URLパターンに型名やパラメーター名を入れる。

views.pyの記述

ルーティングで記述したパラメーター名をビュー関数の引数に指定し、これをテンプレートに渡す。

ここでサーバー起動状態でlocalhost:8000/viewtest/function/1などとURLを指定すると、ブラウザーに以下のように表示される。

クラスベースによる実装

urls.pyの記述

URLパターンにURLパラメーターを記述する方法は関数の場合と同じ。クラスベースビューの場合はas_viewメソッドの実行結果を渡す。

views.pyの記述

クラスベースビューの場合、getなどのメソッドの引数にパラメーターを指定する。引数の指定パターンは関数の場合と同じ。

ここでサーバー起動状態でlocalhost:8000/viewtest/class/2などとURLを指定すると、ブラウザーに以下のように表示される。

GET/POST処理

関数によるビューの実装

テンプレートの準備

GETで表示されるページにフォームを追加し、送信先をfunctionサブディレクトリー、メソッドをPOSTとする。

urls.pyの記述

今回のindexテンプレートはGET、POST両方のリクエストから呼び出されるため、functionサブディレクトリーのルーティング1つ。

views.pyの記述

リクエストメソッドの違いはrequest.methodの文字列で判定して処理を分ける。GETリクエストの場合は1つ目のifブロックが実行され、テンプレートに文字列'GET!'が渡される。またPOSTリクエストの場合は2つ目のifブロックが実行され、テンプレートには文字列'POST!'が渡される。

ここでサーバー起動状態でlocalhost:8000/viewtest/functionなどとURLを指定すると、views.index関数でGETに対応したifブロックが実行され、ブラウザーに以下のようにGET!と表示される。

このページで「送信」ボタンを押すと、今度はviews.index関数でPOSTに対応したifブロックが実行され、ブラウザーにPOST!と表示される。

クラスベースによる実装

テンプレートファイルの準備

POSTに対する処理を関数の場合と分けるため、送信先のURLのサブディレクトリーをclassとする。

urls.pyの記述

GET/POSTに関わらず、classサブディレクトリーでのリクエストを受け取った場合には、IndexViewクラス(のインスタンス)に処理を渡すように定義。

views.pyの記述

ルーティングで

ここでサーバー起動状態でlocalhost:8000/viewtest/classなどとURLを指定すると、views.IndexViewクラスでオーバーライドしたgetメソッドが実行され、ブラウザーに以下のように表示される。

このページで「送信」ボタンを押すと、今度はviews.IndexViewクラスでオーバーライドしたpostメソッドが実行され、ブラウザーに以下のように表示される。

クラスベースビューの基本のまとめ

要点

基本のクラスベースビューの要点は以下のとおり。

  • Viewクラスを継承したクラスを定義
  • GETやPOSTなどに対応したメソッドを定義
  • ルーティングでは、継承先のクラスの.as_view()メソッドを渡す

views.pyの記述

  • django.views.genericパッケージのViewモジュールをインポート
  • Viewクラスを継承したクラスを定義
  • getメソッド、postメソッドなどを定義
    • 第1引数はself
    • 第2引数はrequest
    • パラメーターがあればそれ以降
  • getメソッドの記述内容は、関数ベースの場合の内容と同じ
    • たとえばrender(request, 'target_page')

urls.pyの記述

  • urlpatterns属性のpath関数の第2引数でビュークラスを指定し、このときas_viewメソッドを指定する
    • たとえばpath('sub_dir', views_dir.MyViewClass.as_view())

 

文字コード/符号化

概要

人が読める文字とマシンが処理できる符号を対応させたものが文字コードで、以下の2つの組み合わせ。

符号化文字集合
Coded Character Set: CCS、キャラクターセット。文字ごとに番号を割り当てられた文字の集合。
文字符号化方式
Character Encoding Scheme: CES、エンコーディングルール。符号化文字集合で定義された番号バイト列に返還するルール。

1バイト系

半角系の文字コードは、CCSのコードがそのままバイト列になる。

マルチバイト系

参考サイト

 

ASCII

概要

ASCII (American Standard Code for Information Interchange) はANSIによって規定されたラテン文字のコード体系。

7ビットの2進数(10進数で0~127、16進数で00~7F)にアルファベットなどのラテン文字や記号、制御コードを割り当てている。

符号化文字集合で割り当てられたコードポイントがそのままバイト列表現であり、文字符号化方式を包含している。

文字コードの構成

16進 10進 対応文字
00~1F 0~31 制御文字
20 32 空白文字
21~7E 33~126 アルファベットなどの図形文字
7F 127 制御文字DEL

文字集合と符合化

制御文字

16進 10進 記号 CS ESC 機能
00 0 NUL ^@ \0 ヌル文字
01 1 SOH ^A ヘッディング開始
02 2 STX ^B テキスト開始
03 3 ETX ^C テキスト終了
04 4 EOT ^D 伝送終了
05 5 ENQ ^E 送信問合せ
06 6 ACK -F 送信承認
07 7 BEL ^G \a ベル
08 8 BS ^H \b 後退
09 9 HT ^I \t 水平タブ
0A 10 LF ^J \n ラインフィード(改行)
0B 11 VT ^K \v 垂直タブ
0C 12 FF ^L \f フォームフィード
0D 13 CR ^M \r 復帰
0E 14 SO ^N シフトアウト
0F 15 SI ^O シフトイン
10 16 DLE ^P 伝送制御拡張
11 17 DC1 ^Q 装置制御1
12 18 DC2 ^R 装置制御2
13 19 DC3 ^S 装置制御3
14 20 DC4 ^T 装置制御4
15 21 NAK ^U 否定非承認
16 22 SYN ^V 同期符号
17 23 ETB ^W 伝送ブロック終結
18 24 CAN ^X キャンセル
19 25 EM ^Y 媒体終端
1A 26 SUB ^Z 文字置換
1B 27 ESC ^[ \e エスケープ
1C 28 FS ^\ ファイル分離
1D 29 GS ^] グループ分離
1E 30 RS ^^ レコード分離
1F 31 US ^_ ユニット分離
7F 127 DEL ^? 削除

DEL~削除

厳密には制御文字ではなく、誤った文字を削除するための文字。穿孔テープの時代に削除したい文字の位置でこの文字を打つと下位7ビット全てが1となり、この文字が読み飛ばされた。

DLE (Data Link Escape)~伝送制御拡張

RFC原文は以下のとおり。このコードの後に続く連続したコード群の意味を変更する。すなわちデータ伝送ネットワーク上ににおいてASCIIコード以外の意味を持たせる場合にのみ用いられる。

A communication control character which will change the meaning of a limited number of contiguously following characters. It is used exclusively to provide supplementary controls in data communication networks.

SYN (Synchronous Idle)~同期符号

キャラクター同期方式で、送信する文字列の前後に付加する同期用の文字符合。

図形文字

各欄の上段が文字の印字表現、中段がコードの16進表記、下段がコードの10進表記。

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
20 SP
20
32
!
21
33

22
34
#
23
35
$
24
36
%
25
37
&
26
38

27
39
(
28
40
)
29
41
*
2A
42
+
2B
43
,
2C
44

2D
45
.
2E
46
/
2F
47
30 0
30
48
1
31
49
2
32
50
3
33
51
4
34
52
5
35
53
6
36
54
7
37
55
8
38
56
9
39
57
:
3A
58
;
3B
59
<
3C
60
=
3D
61
>
3E
62
?
3F
63
40 @
40
64
A
41
65
B
42
66
C
43
67
D
44
68
E
45
69
F
46
70
G
47
71
H
48
72
I
49
73
J
4A
74
K
4B
75
L
4C
76
M
4D
77
N
4E
78
O
4F
79
50 P
50
80
Q
51
81
R
52
82
S
53
83
T
54
84
U
55
85
V
56
86
W
57
87
X
58
88
Y
59
89
Z
5A
90
[
5B
91
\
5C
92
]
5D
93
^
5E
94
_
5F
95
60 `
60
96
a
61
97
b
62
98
c
63
99
d
64
100
e
65
101
f
66
102
g
67
103
h
68
104
i
69
105
j
6A
106
k
6B
107
l
6C
108
m
6D
109
n
6E
110
o
6F
111
70 p
70
112
q
71
113
r
72
114
s
73
115
t
74
116
u
75
117
v
76
118
w
77
119
x
78
120
y
79
121
z
7A
122
(
7B
123
|
7C
124
)
7D
125
~
7E
126

括弧の英語表現

()はopening/closing parenthesis、{}はopening/closing brase、[]はopening/closing bracket

その他の記号の英語表現

!はexclamation point、#はnumber sign、*はasterisk、-はhyphen (minus)、.はperiod (decimal point)、/はslant、@はcommercial at、\はreverse slant、^はcircumflex。

コード全体

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00 NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI
10 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS RS GS US
20 SP ! # $ % & ( ) * + , . /
30 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
40 @ A B C D E F G H I J K L M N O
50 P Q R S T U V W X Y Z [ \ ] ^ _
60 ` a b c d e f g h i j k l m n o
70 p q r s t u v w x y z { | } ~ DEL

 

Django – URLパラメーター

URLパラメーターの送信

HTTPリクエストで、以下のようにURLにパラメーターを付して送り、これをDjangoで受け取って処理する手順。

ここではparamtestアプリケーションでパラメーターとして100が送信されるとする。

ルーティングの設定

まずURLに含まれるパラメーターを認識するため、ルーティングを設定する。アプリケーションのurls.pyで、パラメーターを受け取るために以下のように記述する。

<int:....>によってパラメーターが整数形式であることを明示していて、整数以外の値が渡された場合は404エラーとなる。

ビューの記述

ルーティング先のviews.indexでは、このパラメーターを引数で受け取る。以下の例では、受け取ったパラメーターをそのままテンプレートに渡している。

テンプレートが以下のようになっていれば、URLで与えたパラメーターの値がブラウザーにそのまま表示される。

 

 

Django – Tutorial – テンプレート

概要

DjangoドキュメントのチュートリアルPart3中”Write views that actually do something“の冒頭でビュー関数でのモデル操作を実装した後、テンプレートファイルを使った表示を実装している。

テンプレートの基礎についてはこちらを参照。

テンプレートディレクトリー/ファイルの作成

テンプレートファイルの内容

pollsディレクトリー下にtemplatesディレクトリーを、その下にpollsディレクトリーを作成する。そのディレクトリー下に以下の内容でindex.htmlファイルを作成する。

これから、polls/viewsモジュールからこのテンプレートを参照するよう編集していく。

パスの書き方の注意点

テンプレートファイルのアンカータグは以下のように書かれている。

当初/polls/{{ ... }}の部分の先頭の'/'を抜かして書いてしまって、polls/{{ ... }}としたところ、URLが以下のようになってしまった。

http://localhost:8000/polls/polls/2/

現在のアプリケーションからの相対パスになってしまったためで、

http://localhost:8000/polls/ + /polls/2/

と解釈されてしまう。先頭のスラッシュを入れるとホスト名をルートとするパスとなる。ただしこの記事の最後の方にあるDTLのurlタグを使うと、このような心配をしなくて済むようになる。

テンプレートの探索

ディレクトリー・ファイル構成は以下の通り。

config/settings.pyで、以下のように設定している。

  • INSTALLED_APPS'polls.apps.PollsConfig'を登録
    pollsが探索に含まれる
  • TEMPLATES'APP_DIRS'Trueに設定
    polls/templatesが探索に含まれる

ので、polls/templatesとそのサブディレクトリー下がテンプレートファイルの探索場所に含まれる。

ビューにおけるレンダリング

loaderによる標準形

ビューの編集

テンプレートファイルを導入した場合の標準形は以下の構成になる。

  • django.templateパッケージのloaderオブジェクトをインポート
  • loader.get_template('テンプレートへのパス')でテンプレートを読み込み
  • テンプレートのrenderメソッドでレンダリングした結果を、HttpResponseに渡す
    render(context, request)

動作確認

http://localhost:8000/pollsにアクセスすると、2つのリンクが表示される。

 

このHTMLのソースコードは以下のようになっている。

それぞれのリンクをクリックしたときの遷移先URLとブラウザー表示は以下の通り。

  • href="/polls/2/"
    • http://localhost:8000/polls/2/
    • You’re looking at question 2.
  • href="/polls/1/"
    • http://localhost:8000/polls/1/
    • You’re looking at question 1.

renderショートカット

loaderを用いた標準形では、

  1. テンプレートのローダーによってテンプレートファイルを読み込み、
  2. これをレンダリングした結果をHttpResponseに渡す、

という2段階の処理となっている。Djangoにはこれを1行で済ませるrenderショートカットが準備されている。renderショートカットを使って、indexビューをより簡潔にしてみる。

1行目のHttpResponseのインポートはまだ手を入れていない他のビュー関数のためで、renderによる処理には必要ない。loaderのインポートも不要で、必要なのは3行目のrenderのインポートのみ。

14行目がrenderショートカットを導入した効果で、この1行でリクエスト、テンプレート、contextの指定を済ませてレスポンスを返している。

render(request, 'テンプレートパス', context)

404エラーの実装

存在しないidへの反応

indexテンプレートではQuestionの2つの要素が表示され、それぞれid=1, 2をリクエストパラメーターとして渡している(href="/polls/1/"など)。ところがQuestionに存在しないidを指定したURLでアクセスすると以下のようなエラーがブラウザーに表示される。

このエラーの代わりに、404エラーで反応させたい。

例外処理による標準形

ビューの編集

現在のdetailビューは以下のような内容。

存在しないインスタンスを指定すると例外が投げられるので、それをキャッチして404エラーをレイズするようにする。

テンプレートの準備

またrenderで指定しているdetailテンプレートを、polls/template/pollsディレクトリーに以下の内容で作成しておく。

実行結果の確認

これで存在しないidの値を指定したときのエラーは以下のように変化する。メッセージがHttp404クラスのコンストラクターに与えたテキストになっている。

get_object_or_404ショートカット

Djangoには、上のような複数行の例外処理を一行で書くget_object_or_404ショートカットが準備されている。

以下のようにget_object_or_404ショートカットをインポートすると、1行でQuestionデータを取得し、存在しなければ404エラーをレイズしてくれる。

存在しないidを指定したときのエラー表示は以下のようになる。エラーメッセージの内容は固定されていて変更できないようだ。

なおsettings.pyDEBUGFalseにすると、ブラウザー表示は以下の2行のより簡素な内容になる

テンプレートシステム

DTLによる記述

先ほどのindexテンプレートの内容は1行で変数を表示するだけの内容だったが、これをテンプレートらしくDTL~テンプレート言語を使って以下のように書き換える。

そうすると大きな見出しでQuestionデータのテキストが表示され、そのQuestionデータに関連付けられたChoiceデータのテキストが箇条書きで表示される。

 

今回のDTLでは、オブジェクトの属性を得るのにドット検索が行われている。通常のPythonの場合リストや辞書型のオブジェクトの要素は[]で参照されるが、DTLではこの記述方法が使えない。代わりにドットを使って以下の順序で探していく

  1. 辞書型のキー
  2. オブジェクトの属性
  3. リストのインデックス

今回の例では、辞書型のキーで取得できず、オブジェクトの属性として取得に成功する。

URLのハードコーディング回避

ハードコーディングの問題

現時点でindexテンプレートのアンカー要素のURLは"/polls/{{ question_id }}/"と書かれている。

 

この場合にリンクが張られるdetailのURLはurlsで定義されていて、たとえば以下の通り。

http://localhost/polls/1

ここでプロジェクト進行中に以下のように変更することとなったとする。

http://localhost/polls/specifics/1

この場合、indexテンプレートのアンカー要素の内容を全て以下のように変更する必要がある。

href="/polls/specifics/{{ question.id }}/"

さらにindexテンプレート以外でもこのルーティングを使っている場合、その分だけ変更が生じてしまう。

ハードコーディングの回避

urls.pyの確認

まずpolls/urls.pydetailビューへのルーティングにname='detail'で名前が付けられていることに留意。

ビューの変更

index/view.py中、アンカー要素のURL部分を以下のように変更する。

  • href="..."のURL部分を{% url %}に入れ替え
  • このタグの引数に、urlsnameで指定した名前とパラメーターを書く

一般化した書き方は以下の通り。このとき、先頭や末尾の'/'は不要。

{% url 'urlsのnameで定義した名前' クエリーパラメーター %}

HTMLの確認

生成されるHTMLは以下の通り。

URLの変更

URLの変更が必要な場合、1箇所だけ、urlsの内容を変更すればよい。

以下のように生成されるHTMLもすべて変更される。

そして以下のようにアクセスできるようになる。

URLの名前空間管理

名前空間管理の必要性

DTLのurlタグで、ルーティングに付けた名前を使って抽象化することができた。ところが、先の例の場合pollsアプリケーションのdetailと同じ名前を他のアプリケーションでも使う場合、見分けがつかない。

そこで、ルート名がどのアプリケーションのものか分かるようにする必要がある。

urls.pyの編集

urls.pyに以下の1行を追加する。

indexテンプレートの編集

次にindexテンプレートの名前指定部分を、以下のように'アプリケーション名:ルート名'に変更。

この場合の実行結果は変わらないが、他のアプリケーションでもdetailという名前のルーティングがある場合でも、pollsアプリケーションの同名のdetailが識別される。

urlsapp_nameが定義されている状態でurlタグでpolls:を書かないと以下のエラーになる。

 

Django – Tutorial – ビューでの処理

概要

DjangoドキュメントのチュートリアルPart3中”Write views that actually do something“では、それまで単に文字列だけを返してブラウザーに表示させていたビュー関数に、ビューでの処理を記述している。そこではデータベ ースのデータを使った処理を例にしている。

チュートリアルではこれに続いてテンプレートの扱い方を示しているが、ここではモデル操作の実装だけを取り出して整理する。

index関数の編集

チュートリアルで示されているindex関数の編集内容は以下の通り。polls.models.Questionをインポートしていることに注意。

http://localhost:8000/polls/にアクセスすると、questionsテーブルに登録されているデータが日時の新しい順に、カンマで区切られて表示される。

チュートリアルではデータが1つしか登録されていなくて分かりづらいので、もう一つデータを登録してみる。

コードの内容

モデルインスタンスのソートと抽出

Questionモデルの全てのインスタンスをpub_dateフィールドの降順に並べ替えて先頭から5個取出し、そのQuerySetインスタンスをlatest_question_listに参照させている。

  • モデル.objects.order_by()でモデルのデータをソートした結果をQuerySetとして返す
  • '-pub_date'で降順にソート/昇順の場合は'pub_date'
  • [:5]はコレクションのスライスで、先頭から5個のデータ(インデックスが5未満のデータ)を取り出す

シェルで実行してみると以下の通り。

引数を'pub_date'に変更すると並べ替え順序が昇順になり、古いデータから並べられたセットが得られる。

またスライスを[:1]にすると、インデックスが0の要素だけが得られる。

出力文字列の構成

latest_question_listの各要素を', 'をデリミターとして結合している。各要素はQuestionモデルのインスタンスだが、__str__メソッドが実装されているので、参照するとquestion_textの内容が得られる。

 

Django – Tutorial – ビューへのルーティング

概要

DjangoドキュメントのチュートリアルPart3では、ビューへのルーティングやテンプレートの使い方などが詳しく書かれているが、このうちURLconf~ルーティングの部分を整理する。

urls.pyの配置や書き方についてはこちら

view関数の定義

まず、polls/views.pyファイルに3つのview関数(detail, results, vote)を追加する。

いずれのビューでも動作の本質は同じ。

  • リクエストからパラメーターをquestion_idとして受け取る
  • 各ビューで想定している処理の内容に即したテキストをHttpResponseで返す
  • その際、question_idの値もテキストに含めて返す

なおテキストにquestion_idの内容を文字列として含めるために、Pythonの構文を使っている。

"... %s ..." % 変数

urls.pyの設定

追加したview関数をこれに対応したURLリクエストから呼び出すため、ルーティングを追加する。

いずれのルーティングもpollsアプリケーションのビューに関するものなので、最初に作成したpolls/urls.pyに追記する。

確認

サーバー起動状態で各URLを入力したとき、呼ばれるview関数とブラウザー上の文字列は以下のとおり。

  • http://localhost:8000/polls/34/
    views.detail
    →You’re looking at question 34.
  • http://localhost:8000/polls/34/results/
    views.results
    →You’re looking at the results of question 34.
  • http://localhost:8000/polls/34/vote
    views.vote
    →You’re voting on question 34.

URLconf~ルーティングの仕組み

たとえばhttp://ドメイン名/polls/34/というURLでリクエストがあった時、Djangoは以下のように解釈を始める。

  1. settings.pyROOT_URLCONFの設定に従って、config.urlsモジュールを読み込む(モジュールファイルはconfig/urls.py
  2. urlsモジュール中のurl_patterns配列から、パターンを1つずつ順に走査していく
  3. URLパターンが'polls/'パターンまでマッチした時、それ以前のパターンを取り除いて、polls.urlsモジュールを読み込む
  4. polls.urlsモジュールでURLパターンの'<int:question_id>/'パターンまでマッチしてその後がないとき、これに対応するviews.detailモジュールを呼び出す
  5. detailモジュールでは<int:queston_id>の内容が引数のquestion_idに渡され、ビュー内での処理に使われる

なおsettings.pyROOT_URLCONFはデフォルトで以下のように書かれていて、まずconfig.urlsが読み込まれるようになっている。

またconfig.urlsは、チュートリアルの最初の方で以下のように編集済み。

またパラメーターについては<int:question_id>と定義されているので、localhost:8000/polls/abc/のようにパラメーターが整数として解釈されない場合にはパスが見つからず、Page not foundエラーになる。

 

Django-Tutorial-pollsアプリケーション

概要

Djangoドキュメントのチュートリアルに従って、mysiteプロジェクトを作成し、その中にpollsアプリケーションを作成する。

プロジェクトの作成

プロジェクトの作成django-adminで実行する。チュートリアルのプロジェクト構成ではmysiteディレクトリーの下にmysiteサブディレクトリーとしているが、ここではmysite/configという構成にした。

ディレクトリー構成は以下のようになっている。

settings.pyを以下のように編集する(初期設定の詳細はこちら)。

  • ローカルサーバーでの開発のため、ALLOWED_HOSTS'localhost'を設定
  • DATABASESはMySQL用に設定
  • その他、言語コードやタイムゾーンの設定

開発用サーバーを起動して、"Congratulations!"の画面を確認。

pollsアプリケーションの作成

startappコマンドでpollsアプリケーションを作成。

manage.pyは実行可能ファイルなので、以下でも作成できる。

pollsアプリケーション作成後の構成は以下の通り。

view関数の定義

view関数はMTVの構成要素の一つで、URLからルーティングされ、モデルのデータ操作やブラウザー表示のための様々な処理を実装するもの。MVCモデルのコントローラーに相当する。

一般的にはview関数の戻り値にはブラウザー表示のためのテンプレートを渡すが、ここでは最も単純に、単に文字列だけを返すようにする。

  • HttpResponseモジュールをインポート
  • view関数index()を定義
  • HttpResponseのコンストラクターの引数に文字列を渡し、そのインスタンスを戻り値とする

URL conf~ルーティング

URLからview関数index()へのルーティングを設定する。pollsアプリケーションのビューなのでpolls/urls.pyで定義する。アプリケーションのurls.pyはデフォルトでは作成されないので、新たに作成して次の内容とする。

pollsアプリケーションのurlsモジュールをプロジェクトに認識させるため、conf/urls.pyに記述を追加する。

  • django.urlsパッケージのincludeモジュールを追加でインポート
  • path関数でアプリケーションのurls関数をインポートし、アプリケーションのURLに紐づけ

確認

サーバーが起動した状態で、サブディレクトリーpolls/にアクセスする。今の構成ではlocalhost:8000/polls

ブラウザーの画面には、以下のテキストが表示される。

 

 

Django – Tutorial – admin

概要

Djangoのチュートリアル、管理者ページの部分を整理。

管理者ログインページ

Djangoのデフォルトの状態で、既に管理者の環境が準備されている。サーバーを起動してadmin/サブディレクトリーでアクセスすると、以下のような管理者ログイン画面が表示される。

管理者の作成

createsuperuserコマンドで管理者を作成する。

管理者のユーザー名、メールアドレス、パスワードを登録し、管理者アカウント作成。プロンプトの一部が日本語になっている。

パスワードを'admin'という文字列を含むかなり簡単なものにしたため「ユーザー名と似すぎています」という警告が出たが、ここはyesにしておいた。

管理者ログイン・インデックスページ表示

作成した管理者アカウントでログインすると管理者インデックスページへ。この段階では、pollsアプリケーションが管理者で操作できるようにはなっていない。

管理者へのアプリケーションの登録

管理者がpollsアプリケーションを操作できるようにするために、polls/admin.pyに記述を追加する。

  • Qustionモデルのインポート
  • adminサイトにQuestionモデルを登録

admin.pypollsパッケージ内にあるのでfrom .models ...としているが、from polls.models ...でもよい。

インデックスページを再表示させると、今度はQuestionsが見られるようになった。

データの内容表示

インデックスページのQustionsをクリックすると、登録済みデータが表示される。What’s up?と表示されているのは、models.pyQuestionクラスで__str__メソッドを定義したおかげで、デフォルトの状態だとQuestion object (1)と表示される。

What’s upをクリックすると、フィールド内容の編集画面に移る。

フィールド名のQustion textDate publishedは、models.pyQuestionクラスで定義したフィールド名になっている。

  • Question textは、クラス定義のプロパティーquestion_textのアンダースコアがスペースに、先頭が大文字に変換されたもの
  • Date publishedDateTimeFieldの引数に指定した'date published'の先頭が大文字に変換されたもの

たとえば上記の3行目をDateTimeField()とすると、画面表示は元のプロパティー名に即してPub dateとなる。

データの編集

Qustion textDate publishedの内容を変更して「保存して編集を続ける」ボタンを押すと、変更した内容が反映される。

もちろんデータベース上でも変更されている。

変更履歴

画面右上の「履歴」ボタンを押すと変更履歴画面に移り、Question textDate publishedが変更された履歴が表示される。