繼續編寫投票應用,專註於簡單的表單設計,並精簡使用的代碼。
更新一下先前編寫的投票詳細頁面的模板 ("polls/detail.html") ,讓它包含一個 HTML 元素:
檔案路徑: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>
簡要說明:
上面的模板在 Question 的每個 Choice 前添加一個單選按鈕。
每個單選按鈕的 value 屬性是對應的各個 Choice 的 ID。每個單選按鈕的 name 是 "choice" 。
這意味著,當有人選擇一個單選按鈕並提交表單提交時,它將發送一個 POST 數據 choice=# ,其中# 為選擇的 Choice 的 ID。這是 HTML 表單的基本概念。
我們設置表單的 action 為 {% url 'polls:vote' question.id %} ,並設置 method="post" 。
使用 method="post"(與其相對的是
method="get"`)是非常重要的,因為這個提交表單的行為會改變服務器端的數據。 無論何時,當你需要創建一個改變服務器端數據的表單時,請使用 ``method="post" 。
這不是 Django 的特定技巧;這是優秀的網站開發技巧。
forloop.counter 指示 for 標簽已經循環多少次。
由於我們創建一個 POST 表單(它具有修改數據的作用),所以我們需要小心跨站點請求偽造。 謝天謝地,你不必太過擔心,因為 Django 已經擁有一個用來防禦它的非常容易使用的系統。
簡而言之,所有針對內部 URL 的 POST 表單都應該使用 {% csrf_token %} 模板標簽。