しゃちの備忘録

プログラミングを中心とした技術関連の備忘録です(今のところ)

Djangoに触る(その7)

7日目です.

チュートリアルの続きに挑みます.

前回まで

teru0rc4.hatenablog.com

ビューのハードコーディング改善,URLの名前空間の改善を行いました.

今日やったところ

はじめての Django アプリ作成、その 4 | Django documentation | Django

フォーム作成とコードの縮小化についてです.

フォームの作成

前回ビューの部分の修正を行いました. 今回はそこにhtmlの formを追加します.

polls/templates/polls/detail.htmlを以下に変更します. 今回はラジオボタンを追加しました.

これの追加で質問の選択肢が追加できたと思います.

<h1>{{ question.question_text }}</h1>

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
    <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>

送信したデータを処理するための変更を施していきます. polls/urls.pyには,実はすでに必要なものは書かれています.

url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),

なのであとは,polls/view.pyを修正すればOKです. 以下の内容を追記してあげてください.

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse

from .models import Choice, Question
# ...
def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

また質問の投票を行った時のリダイレクト処理も実装します. 同じく,polls/views.pyに対して,追記します

from django.shortcuts import get_object_or_404, render


def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/results.html', {'question': question})

最後に実際に表示されるwebページのテンプレートとして, polls/templates/polls/result.htmlを作成します.

<h1>{{ question.question_text }}</h1>

<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>

<a href="{% url 'polls:detail' question.id %}">Vote again?</a>

これで投票をするとリダイレクトしてくれたり, 選択せずに投票をすると,エラーを吐く仕組みができました. お疲れ様でした.

おわりに

ぼちぼちでチュートリアルが終わるので,実際に手を動かしたいですね….

追記

やっぱり一回自分が何をやってきたか再確認する意味も兼ねて, 明日からは今日までの範囲を改めて見直しながら, 何か作りたいと思います.

ので毎日更新も一度今日までです.

作った何かの進捗を報告することはあるかもしれません.

チュートリアルの続きは詰まったその時にやりたいと思います.