<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>
簡要介紹:
現在,讓我們建立一個處理提交的資料的一個 Django 檢視。
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
我們還建立了一個虛擬實現 vote() 函式。現在建立一個實用的版本。新增到以下程式碼到檔案 polls/views.py:
from django.shortcuts import get_object_or_404, render from django.http import HttpResponseRedirect, HttpResponse from django.core.urlresolvers 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,)))
此程式碼包含還沒有在本教學中涉及幾個東西:
request.POST是一個類似於字典的物件,使您可以通過鍵名存取提交的資料。在這種情況下,request.POST['choice'] 返回被選擇的choice的ID,作為字串。 request.POST的值總是字串。
注意:Django還提供 request.GET 以相同的方式存取 GET資料 – 但我們明確使用 request.POST 在我們的程式碼,以確保資料只能通過POST呼叫修改。
如果POST資料未提供choice,request.POST['choice']將引發KeyError異常。上面的程式碼檢查KeyError異常和錯誤訊息顯示問題的表單,如果沒有給出 choice。
選擇choice計數遞增後,程式碼返回 HttpResponse 重定向,而不是一個正常的 HttpResponse。HttpResponseRedirect 需要一個引數:使用者將被重定向到URL(請參閱下面-我們如何構建在這種情況下的URL)。
如上Python的註釋所指出的,應該總是在 POST 資料處理成功後返回一個HttpResponse重定向。
在本例中我們使用的是 HttpResponseRedirect 構造reverse()函式。此函式有助於避免寫死URL在檢視中。這是因為我們想通過控制並指向該檢視的URL模式的可變部分的檢視的名稱。在這種情況下,使用 URLconf 組態使 reverse()呼叫返回字串如:
'/polls/3/results/'
其中3是question.id的值。然後,這個重定向的URL將呼叫「results」檢視中顯示的最後一頁。
現在存取網址:http://127.0.0.1:8000/polls/1/ 得到結果如下所示:
當有人在一個問題投票後,vote() 檢視重定向到該問題的結果頁面。讓我們編寫這個檢視(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})
現在,建立一個 polls/results.html (polls/templates/polls/results.html)模板:
<h2>{{ question.question_text }}</h2> <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>
現在,在瀏覽器中開啟 /polls/1/ 並表決的問題。應該會被每次投票時看到更新結果頁。如果您提交表單不選擇一個選項,應該看到錯誤訊息。
選擇選項,提交後顯示如下結果:
首先,開啟 polls/urls.py 並修改如下:
from django.conf.urls import url from . import views app_name = 'polls' urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index'), url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'), url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'), url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), ]
請注意,第二和第三模式的正規表示式匹配的模式名稱已經從<question_id>改變為<to>。
接下來,我們要刪除舊的 index, detail, 和 results 檢視使用Django通用檢視代替。要做到這一點,開啟 polls/views.py 檔案並修改它如下:
from django.shortcuts import get_object_or_404, render from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from django.views import generic from .models import Choice, Question class IndexView(generic.ListView): template_name = 'polls/index.html' context_object_name = 'latest_question_list' def get_queryset(self): """Return the last five published questions.""" return Question.objects.order_by('-pub_date')[:5] class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' class ResultsView(generic.DetailView): model = Question template_name = 'polls/results.html' def vote(request, question_id): ... # same as above
剩下的你自己發揮了,包教不包會,請參考:https://docs.djangoproject.com/en/1.9/intro/tutorial04/