トップ 一覧 ping 検索 ヘルプ RSS ログイン

Django 最初のアプリケーション 4の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!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エレメントを持つように変更
 <h1>{{ poll.question }}</h1>
 {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
 <form action="/polls/{{ poll.id }}/vote/" method="post">
 {% for choice in poll.choice_set.all %}
     <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
     <label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br/>{% endfor %}
 <input type="submit" value="vote" />
 </form>
{{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<poll_id>\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/'

!結果表示テンプレートの作成

 <h1>{{ poll.question }}</h1>
         
 <ul>
 {% for choice in poll.choice_set.all %}
     <li>{{ choice.choice }} -- {{ choice.votes }} vote{{choice.votes|pluralize}}</li>
 {% endfor %}
 </ul>
::投票すると結果表示される
*結果表示
{{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.