1. 程式人生 > >編寫你的第一個Django應用程序,第四部分

編寫你的第一個Django應用程序,第四部分

次數 用戶 進行 訪問 觀點 ken span .py return

本教程從隨筆三停止的地方開始。這裏將重點放簡單的表單處理和削減我們的代碼。

寫一個簡單的表單

更新模版文件polls/detail.html,以便包含一個html<form>元素:

<body>
    <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> </body>

說明:

  • 上面的模版為每個問題選項顯示一個單選按鈕。value按鈕相關聯的是問題的選擇的ID。name為每個單選按鈕的choice。這意味著,當有人選擇其中一個單選按鈕並提交表單時,它將發送post數據choice=#,#表示所選選項的id。
  • forloop.counter表示for標簽經過其循環的次數
  • 由於我們正在創建POST表單(可能會影響其循環的次數)。簡而言之,所有以內部URL為目標的POST表單都應使用模版標記:{% csrf_token %}

表單寫完,就創建一個處理提交數據的django視圖。並對其進行處理。

打開polls/views.py文件編寫代碼:

from django.urls import reverse

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):
        return render(request,polls/detail,{
        question:question,
        error_message:"You didn‘t select a choice.",
    })
    else:
        selected_choice.votes+=1
        selected_choice.save()
        return HttpResponse(reverse(polls:results,args=(question_id)))

這段代碼包含本教程尚未涉及的一些內容:

  • request.POST是一個類似字典的對象,可以通過key訪問提交的數據。request.POST[‘choice‘]以字符串形式返回所選項的ID。
  • 如果request.POST[‘choice‘] KeyError,在POST數據中沒有提供。將會引發error。上面的代碼會檢查並重新顯示問題並顯示錯誤消息。You didn‘t select a choice.
  • 增加了一個票數選擇計數,代碼將返回一個HttpResponseRedirect。而不是一個正常的response。HttpResponseRedirect只有一個參數:用戶將被重定向到URL。
  • reverse()調用將返回一個類似的字符串:‘/polls/3/results/‘。這個將重定向的URL會調用‘results’視圖顯示最終結果。

技術分享圖片

當人在問題中投票後,該vote()視圖將到results頁面。我們來寫下這個觀點:

polls/views.py:

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

可以看出,這和detail視圖幾乎一樣。等下解決此冗余。

再去模版目錄下創建:polls/results.html

<body>
    <h1>{{ question.question_text }}</h1>
    <ul>
        {% for choice in question.choice_set.all %}
        <li>
            {{ choice.choice_text }} -- {{ choice.votes }}
            票
        </li>
        {% endfor %}
    </ul>
    <a href="{% url ‘polls:detail‘ question.id %}">繼續投票?</a>
</body>
</html>

現在,可以進行投票了。輸入127.0.0.1/polls 然後一直點擊下去。

技術分享圖片

使用通用視圖

之前有提到兩個視圖代碼幾乎一樣。冗余的,django提供了一個稱為‘通用視圖‘系統的快捷方式。

將會:

  1. 轉換URLconf
  2. 刪除一些舊的不需要的視圖
  3. 基於django的通用視圖引入新的視圖

修改URL配置

首先打開polls/urls.py更改代碼:

編寫你的第一個Django應用程序,第四部分