django系列8:優化vote頁面,使用通用視圖降低代碼冗余
阿新 • • 發佈:2018-10-19
教程 可用 nbsp docs esp last resp att cti
修改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>
修改views.py中vote的部分,和detail.html聯合起來,記錄票數,編輯對應的操作反饋
from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import get_object_or_404, render 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,)))
裏面用到了重定向,HttpResponseRedirect,重定向頁面到 polls:results,傳入的content是question.id,這裏對投票完成頁面的results的views做優化
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})
創建一個results.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>
details和results的view 有很多代碼相同之處,這裏修改為使用通用視圖,降低代碼冗余
修改conf
from django.urls import path from . import views app_name = ‘polls‘ urlpatterns = [ path(‘‘, views.IndexView.as_view(), name=‘index‘), path(‘<int:pk>/‘, views.DetailView.as_view(), name=‘detail‘), path(‘<int:pk>/results/‘, views.ResultsView.as_view(), name=‘results‘), path(‘<int:question_id>/vote/‘, views.vote, name=‘vote‘), ]
修改views
from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, render from django.urls 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, no changes needed.
至此,教程結束。
剩余的測試代碼部分,優化界面部分,打包和引用部分,已經執行過,但是篇幅太長,建議直接登錄官網查閱文檔。
https://docs.djangoproject.com/en/2.1/intro/tutorial06/
django系列8:優化vote頁面,使用通用視圖降低代碼冗余