上善若水。水善利萬物而不爭
——老子《道德經(jīng)》
本節(jié)內(nèi)容
- 網(wǎng)頁中的表單定義
- 表單提交數(shù)據(jù)的處理
1. 網(wǎng)頁中的表單定義
網(wǎng)頁中的表單是前端頁面中非常重要的一部分剧辐,我們結(jié)合官方文檔進(jìn)行講解
首先改造我們的問題詳細(xì)信息頁面details.html
趁曼,用于展示問題的同時,展示對應(yīng)的解決方案乱豆;對于解決方案可以進(jìn)行投票
1.1 改造mysite/polls/templates/details.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>詳細(xì)問題展示</title>
<link rel="stylesheet" href="">
</head>
<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>
{% endfor %}
<input type="submit" value="Vote投票">
</form>
</body>
</html>
在上述代碼中,出現(xiàn)了大量的之前的章節(jié)中沒有介紹的內(nèi)容彩库,我們一一說明一下苞冯。
-
action="{% url 'polls:vote' question.id %}"
:表單中的action是要提交的地址,我們通過配置化的URL路由進(jìn)行處理 -
forloop.counter
:表示循環(huán)當(dāng)前正在進(jìn)行的次數(shù)侧巨,第一次循環(huán)(1),第二次循環(huán)(2)以此類推
*question.choice_set.all
:通過question
對象鞭达,關(guān)聯(lián)查詢對應(yīng)的所有的Choice
對象(對應(yīng)的查詢過程司忱,Django在底層已經(jīng)幫我們自動處理了,類似select * from choice where question_id = #{id}
) -
error_message
:這個是我們后面再改造detail視圖處理函數(shù)時畴蹭,要添加的一個保存錯誤信息的變量坦仍,這里主要用于展示錯誤信息
*{%csrf_token%}
:這是一個Django內(nèi)置的指令,主要用于預(yù)防跨域請求偽造攻擊的(在其他的網(wǎng)頁應(yīng)用中叨襟,偽造的跨域請求攻擊是一件讓人頭疼的事情繁扎,Django這點做的非常棒呢!)
注意:關(guān)于模板視圖和模型對象中用到的大部分的API,后續(xù)的章節(jié)中會有介紹的哦梳玫,支持一下我們吧
1.2 改造視圖處理函數(shù)views.vote
接下來爹梁,對于表單提交的數(shù)據(jù),我們需要在視圖處理函數(shù)中接收到并且進(jìn)行后續(xù)的處理
# 定義投票結(jié)果
def vote(request, question_id):
# 獲取查詢的問題對象
question = get_object_or_404(Question, pk=question_id)
print(request.POST)
try:
select_choice = question.choice_set.get(pk=request.POST['choice'])
except Exception as e:
print(e)
return render(request, "details.html",
{
"question": question,
"error_message": "你的問題還沒有發(fā)布解決方案"
})
else:
# 投票數(shù)量增加1
select_choice.votes += 1
# 保存到數(shù)據(jù)庫
select_choice.save()
# 代碼中使用配置的方式跳轉(zhuǎn)到指定的路由
return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))
對于上述代碼提澎,我們做一個簡單的介紹姚垃,相信大家也就能看得明白了
-
request.POST
:是一個用于接收表單通過POST提交的數(shù)據(jù)的方式 -
request.POST["choice"]
:就是接收用戶通過POST方式提交的表單中屬性為choice
的數(shù)據(jù)的,類似的還有request.GET['attr']
盼忌;通過這樣的方式獲取數(shù)據(jù)积糯,有可能會出現(xiàn)異常(當(dāng)屬性在表單中不存在時出現(xiàn)KeyError
異常) -
HttpResponseRedirect
:這是類似前面我們學(xué)過的HttpResponse處理類,主要是用于響應(yīng)用戶的請求處理的谦纱,它比HttpResponse
更加好用的是可以附帶獨立的參數(shù)列表看成;最后響應(yīng)的是用戶的請求會被重定向而不是轉(zhuǎn)發(fā)。 -
reverse()
:這個函數(shù)主要是將之前我們處理的過程中操作的硬編碼格式跨嘉,轉(zhuǎn)換成路由配置的格式川慌,方便統(tǒng)一維護(hù)的操作。
1.3 改造results
視圖函數(shù)和mysite/polls/templates/results.html
界面
views.results
視圖處理函數(shù)主要是用于進(jìn)行問題數(shù)據(jù)查詢并跳轉(zhuǎn)到視圖界面的偿荷,如下:
def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, "results.html", {"question":question})
results.html網(wǎng)頁主要是用于進(jìn)行問題和對應(yīng)解決方案的展示使用的窘游,和details.html界面大同小異
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 展示問題信息 -->
<h2>{{question.question_text}}</h2>
<!-- 循環(huán)遍歷所有的解決方案 -->
<ul>
{% for c in question.choice_set.all %}
<li>方案:{{c.choice_text}}----[投票結(jié)果{{c.votes}}]vote{{ c.votes|pluralize }}</li>
{% endfor %}
</ul>
<a href="{% url 'polls:detail' question.id%}">繼續(xù)投票?</a>
</body>
</html>
1.4, 功能測試
接下來,我們重啟項目跳纳,開始投票功能的測試
打開首頁
首頁問題列表
查看問題信息details.html頁面查看問題的詳細(xì)信息
投票處理
results.html頁面展示投票結(jié)果
這節(jié)關(guān)于表單的處理就先介紹到這里忍饰,對于大家常規(guī)的項目使用已經(jīng)可以完全滿足了。下一節(jié)內(nèi)容將對我們頁面中的樣式進(jìn)行處理寺庄,讓頁面看著更加的優(yōu)美
Django來敲門