Djangoに触る(その4)
4日目です.
チュートリアルの続きに挑みます
前回まで
テーブルの作成についての整理と, チュートリアルを進めadminのセッティングを行いました..
今日やったところ
はじめての Django アプリ作成、その 3 | Django ドキュメント | Django
ビューに関して,polls/view.py
などを修正しました.
ビューの追記
前々回polls
にアクセスした時のビューを結構あっさり作ったのですが,
今回はそこの部分をもう少し掘り下げ,かっこいい見た目にしていこうと思います
polls/view.py
を次の内容を追記します.
def detail(request, question_id): return HttpResponse("You're looking at question %s." % question_id) def results(request, question_id): response = "You're looking at the results of question %s." return HttpResponse(response % question_id) def vote(request, question_id): return HttpResponse("You're voting on question %s." % question_id)
また,polls/url.py
の内容は以下のように書き換えます.
url()
を追記して,更新した`polls/view.py
に対応する形にしました.
from django.conf.urls import url from . import views urlpatterns = [ # ex: /polls/ url(r'^$', views.index, name='index'), # ex: /polls/5/ url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), # ex: /polls/5/results/ url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'), # ex: /polls/5/vote/ url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), ]
この状態でpython3 manage.py runserver
をし,
http://127.0.0.1:8000/polls/29/にアクセスをするとこのような画面になります.
http://127.0.0.1:8000/polls/
以下に数字を入れてアクセスすると,URLで指定した数字が出力されます.
何が起きているのかというと,
たとえば,今回のようにhttp://127.0.0.1:8000/polls/29/
に対してアクセスし,リクエストを送ると,
Djangoはmystic/setting.py
の中のROOT_URLCONF = 'mysite.urls'
という部分を参照し,
mystie/url.py
をロードをします.
mystie/url.py
に従い与えられたURLを検査しpolls/
に該当する処理を見つけたあと,
/polls
を取り除いた残り/29
をpolls/url.py
に引き渡し,
この表現がr'^(?P<question_id>[0-9]+)/$'
に合致するのでdetailを呼び出してその結果として,
URLにIDを打ち込むだけで,対応した画面を出力してくれるというわけです.
これの強みとしては,URLのマッチングには正規表現を使っているため,基本的に制限はなく,
同時に.html
などの追加もいらない点が挙げられます.
ちゃんと動作を持つビューを作る
ここまでではあくまで表示しているだけで,ビューにとって大事な要素を満たしているとは言えません.
それはリクエストに対して季節なHttpResponseを返すことと,例外をしっかり返すことです.
以降ではそれらをindex()
を変更しながら実装したいと思います.
まずはpolls/views.py
を次のように追記いたします.
やっていることはindex()
の書き換えです.その他部分は残しておいてください.
from django.http import HttpResponse from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] output = ', '.join([q.question_text for q in latest_question_list]) return HttpResponse(output)
しかしこのコード,記法状は問題はないのですが,システムとして問題を抱えています. それはビューの内容を直接書き込んでしまっていることです. このままでは,ページの見栄えを変更するたびにこのPythonコードを編集せねばなりません.
そこで,このビューの部分をPythonから切り離したいと思います. そのためにDjangoのテンプレート機能とhtmlファイルを利用します.
まずはpolls
ディレクトリの中にtemplates
というディレクトリを作成します.
そしてその中にpolls
(誤字ではないです)を作成します.
そしてその中にindex.html
を作成します.
つまりpolls/templates/polls/index.html
になるわけです.
何故こんなことをしているのかというと,Djangoのテンプレートのロードと, 同名のテンプレートを作った際の区別を簡単に明確化する目的があります. 詳しくは公式ドキュメントに書いてあるので是非ご参照ください(はじめての Django アプリ作成、その 3 | Django ドキュメント | Django)
肝心のindex.html
ですが次のように記入します.
{% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %}
また,テンプレート適用のためにpolls/view.py
のindex()
も次のように変更します.
from django.http import HttpResponse from django.template import loader from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = { 'latest_question_list': latest_question_list, } return HttpResponse(template.render(context, request))
この状態でサーバーを立てpolls/
にアクセスすると,questionの質問リストを表示します.
何もなければNo polls are available
と言われます
質問を追加する場合は
はじめての Django アプリ作成、その2 | Django ドキュメント | Django
を見ながら追加してみましょう.
おわりに
ビューのリクエストまで作成しました.
明日はもうちょっと進めるといいですね….
というか,機能はなんとなくぽよっとわかったので, 1回思ったものがどこまでできるかーをやってもいいのかなーと思ってたりします.
うーん.