ruk·si

🍡 Django Tutorial
View Function Handler

Updated at 2018-11-23 18:27

Create form for choice vote buttons, handle receiving the votes and show results.

Edit polls/templates/polls/detail.html:

<h1>{{ 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.choices.all %}
        <input
            type="radio"
            name="choice"
            id="choice{{ forloop.counter }}"
            value="{{ choice.id }}"
        />
        <label for="choice{{ forloop.counter }}">{{ choice.text }}</label>
        <br />
    {% endfor %}
    <input type="submit" value="Vote" />
</form>

Edit polls/views.py:

from uuid import UUID

from django.core.exceptions import ObjectDoesNotExist
from django.db.models import F
from django.http import HttpRequest, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse

from .models import Question

# ...

def vote(request: HttpRequest, question_id: UUID):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choices.get(pk=request.POST.get('choice'))
    except ObjectDoesNotExist:
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    # increment with database operation avoiding race condition
    # use `with transaction.atomic():` for more complex operations
    selected_choice.votes = F('votes') + 1
    selected_choice.save()
    return HttpResponseRedirect(reverse('polls:results', kwargs={'pk': question.id}))

Try out the new forms:

python manage.py runserver