!!!Django 最初のアプリケーション 4 [Django][Python][[[前|Django 最初のアプリケーション 3]]] Pythonの概要も分かり易い. {{amazon 477413760X}} *[The Django Book|http://www.djangobook.com/en/1.0/] *SVN release http://docs.djangoproject.com/en/dev/intro/tutorial04/ *Django 1.0 http://docs.djangoproject.com/en/1.0/intro/tutorial04/ Django 1.0を参考にサンプルアプリケーションを作成してみる !!シンプルなフォームの作成 *[Django 最初のアプリケーション 3]で作成した、Poll詳細テンプレートを、HTML Formエレメントを持つように変更

{{ poll.question }}

{% if error_message %}

{{ error_message }}

{% endif %}
{% for choice in poll.choice_set.all %}
{% endfor %}
{{ref_image django_firstapp31.jpg}} *ラジオボタンは、Choide IDと結び付けられており、名前は "choice"。選択して、サブミットしたときには、POSTデータは choice=3 のようになる。 *Formエレメントのactionに /polls/{{ poll.id }}/vote/ とし、method="post"としたが、これはDjangoに限らず、Web開発では重要。 *fooloop.counter は、何回ループカウンタが回ったかをあらわす !!投票ビュー、結果表示ビューの作成 *Django 最初のアプリケーション 3を思い出して、Voteビューを作成する *mysite/polls/urls.py には、以下のように記述していた (r'^(?P\d+)/vote/$', 'vote'), !vote()、results()関数の記述 *mysite/polls/views.py にvote()、results()関数を記述する # -*- coding: utf-8 -*- from django.shortcuts import render_to_response, get_object_or_404 from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from mysite.polls.models import Choice, Poll def index(request): latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] return render_to_response('polls/index.html',{'latest_poll_list': latest_poll_list}) def detail(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) return render_to_response('polls/detail.html', { 'poll': p }) def vote(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) try: selected_choice = p.choice_set.get(pk=request.POST['choice']) except (KeyError, Choice.DoesNotExist): # 投票ページの再表示 return render_to_response('polls/detail.html', { 'poll': p, 'error_message': "You didn't select a choice.", }) else: selected_choice.votes +=1 selected_choice.save() # 処理成功後は常にPOSTデータとともにHttpResponseRedirectを返す # これはユーザの2度押しによる再送信を防止する return HttpResponseRedirect(reverse('mysite.polls.views.results', args=(p.id,))) def results(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) return render_to_response('polls/results.html', {'poll': p}) ::request.POST *request.POST はディクショナリのようなオブジェクトで、サブミットされたデータをキーにより取得できる。上記の例では、request.POST['choice'] で、選択されたChoiceを文字列として取得できる *request.POSTの値は常に文字列 *Djangoは同様に、request.GETも提供する。 *POSTデータとして送信されてこない場合、request.POST['choice'] は KeyErrorを引き起こす。 ::HttpResponseRedirect *Choiceのカウントをインクリメントした後、HttpResponseではなく、コードのコメントにある理由から、HttpResponseRedirectを返すほうがよい。HttpResponseRedirectはリダイレクト先のURLを引数として1つ取る。 ::reverse() *HttpResponseRedirectで、reverse()関数をを使用しているが、この関数は、ビュー関数にURLをハードコーディングするのを避けるため。 *制御を渡したいビュー名および、そのビューを指すURLパターンの一部が変数として得られる。 *今回、Django 最初のアプリケーション 3で行った設定では、reverse()は、以下のような文字列を返す '/polls/3/results/' !結果表示テンプレートの作成

{{ poll.question }}

::投票すると結果表示される *結果表示 {{ref_image django_firstapp32.jpg}} *選択せずに投票でエラーメッセージ {{ref_image django_firstapp33.jpg}} !!ジェネリックビューを使う : コードの削減 *detail()、results()、index()これらのビューは基本的なWeb開発の典型である。 *以下はとても一般的なので、Djangoは"ジェネリックビュー"というショートカットを提供する **URLから取得したパラメータでデータベースからデータを取得 **テンプレートをロードして、レンダリングしたテンプレートを返す *ジェネリックビューは共通パターンを抽象化する。 Generic views abstract common patterns to the point where you don't even need to write Python code to write an app.