在此之前我們已經(jīng)編寫了 Blog 的首頁(yè)視圖,并且配置了 URL 和模板嗓化,讓 Django 能夠正確地處理 HTTP 請(qǐng)求并返回合適的 HTTP 響應(yīng)。不過(guò)僅僅在首頁(yè)返回了一句話:訪問(wèn)我的第一個(gè)博客首頁(yè)谬哀。這是個(gè) Hello World 級(jí)別的視圖函數(shù)刺覆,我們需要編寫真正的首頁(yè)視圖函數(shù),當(dāng)用戶訪問(wèn)博客首頁(yè)時(shí)玻粪,他將看到我們發(fā)表的博客文章列表隅津。
首頁(yè)視圖函數(shù)
上一節(jié)闡明了 Django 的開(kāi)發(fā)流程。即首先配置 URL劲室,把 URL 和相應(yīng)的視圖函數(shù)綁定伦仍,一般寫在 urls.py 文件里,然后在工程的 urls.py 文件引入很洋。其次是編寫視圖函數(shù)充蓝,視圖中需要渲染模板,我們也在 settings.py 中進(jìn)行了模板相關(guān)的配置,讓 Django 能夠找到需要渲染的模板谓苟。最后把渲染完成的 HTTP 響應(yīng)返回就可以了官脓。相關(guān)的配置和準(zhǔn)備工作都在之前完成了,這里只需專心編寫視圖函數(shù)涝焙,讓它實(shí)現(xiàn)我們想要的功能即可卑笨。
首頁(yè)的視圖函數(shù)其實(shí)很簡(jiǎn)單,代碼像這樣:
在前面講解過(guò)模型管理器objects的使用仑撞。這里使用all()方法從數(shù)據(jù)庫(kù)里獲取了全部的文章赤兴,存在了post_list變量里。all方法返回的是一個(gè)QuerySet(可以理解成一個(gè)類似于列表的數(shù)據(jù)結(jié)構(gòu))隧哮,由于通常來(lái)說(shuō)博客文章列表是按文章發(fā)表時(shí)間倒序排列的桶良,即最新的文章排在最前面,所以緊接著調(diào)用了order_by方法對(duì)這個(gè)返回的 queryset 進(jìn)行排序沮翔。排序依據(jù)的字段是created_time陨帆,即文章的創(chuàng)建時(shí)間。-號(hào)表示逆序采蚀,如果不加-則是正序疲牵。 接著如之前所做,渲染了 blog\index.html 模板文件搏存,并且把包含文章列表數(shù)據(jù)的post_list變量傳給了模板瑰步。
處理靜態(tài)文件
項(xiàng)目使用了從網(wǎng)上下載的一套博客模板,這里面除了 HTML 文檔外璧眠,還包含了一些 CSS 文件和 JavaScript 文件以讓網(wǎng)頁(yè)呈現(xiàn)出我們現(xiàn)在看到的樣式缩焦。同樣需要對(duì) Django 做一些必要的配置,才能讓 Django 知道如何在開(kāi)發(fā)服務(wù)器中引入這些 CSS 和 JavaScript 文件责静,這樣才能讓博客頁(yè)面的 CSS 樣式生效袁滥。
按照慣例,把 CSS 和 JavaScript 文件放在blog 應(yīng)用的 static\ 目錄下灾螃。因此题翻,先在blog 應(yīng)用下建立一個(gè) static 文件夾。同時(shí)腰鬼,為了避免和其它應(yīng)用中的 CSS 和 JavaScript 文件命名沖突(別的應(yīng)用下也可能有和 blog 應(yīng)用下同名的 CSS 嵌赠、JavaScript 文件),我們?cè)僭?static\ 目錄下建立一個(gè) blog 文件夾熄赡,把下載的博客模板中的 css 和 js 文件夾連同里面的全部文件一同拷貝進(jìn)這個(gè)目錄姜挺。最終我們的 blog 應(yīng)用目錄結(jié)構(gòu)應(yīng)該是這樣的:
用下載的博客模板中的 index.html 文件替換掉之前我們自己寫的 index.html 文件。如果你好奇彼硫,現(xiàn)在就可以運(yùn)行開(kāi)發(fā)服務(wù)器炊豪,看看首頁(yè)是什么樣子凌箕。
如圖所示,你會(huì)看到首頁(yè)顯示的樣式非炒什常混亂牵舱,原因是瀏覽器無(wú)法正確加載 CSS 等樣式文件。需要以 Django 的方式來(lái)正確地處理 CSS 和 JavaScript 等靜態(tài)文件的加載路徑缺虐。CSS 樣式文件通常在 HTML 文檔的 head 標(biāo)簽里引入芜壁,打開(kāi) index.html 文件,在文件的開(kāi)始處找到 head 標(biāo)簽包裹的內(nèi)容志笼,大概像這樣:
CSS 樣式文件的路徑在 link 標(biāo)簽的 href 屬性里沿盅,而 JavaScript 文件的路徑在 script 標(biāo)簽的 src 屬性里把篓∪依#可以看到諸如 `href="css/bootstrap.min.css" 或者 src="js/jquery-2.1.3.min.js" 這樣的引用,由于引用文件的路徑不對(duì)韧掩,所以瀏覽器引入這些文件失敗紊浩。需要把它們改成正確的路徑。把代碼改成下面樣子疗锐,正確地引入 static 文件下的 CSS 和 JavaScript 文件:
把引用路徑放在了一個(gè)奇怪的符號(hào)里坊谁,例如:href="{% static 'blog/css/bootstrap.min.css' %}"。用 {% %} 包裹起來(lái)的叫做模板標(biāo)簽滑臊。前面說(shuō)過(guò)用 {{ }} 包裹起來(lái)的叫做模板變量口芍,其作用是在最終渲染的模板里顯示由視圖函數(shù)傳過(guò)來(lái)的變量值。而這里使用的模板標(biāo)簽的功能則類似于函數(shù)雇卷,例如這里的static模板標(biāo)簽鬓椭,它把跟在后面的字符串'css/bootstrap.min.css'轉(zhuǎn)換成正確的文件引入路徑。這樣 css 和 js 文件才能被正確加載关划,樣式才能正常顯示小染。
替換完成后你可以刷新頁(yè)面并看看網(wǎng)頁(yè)的源代碼,看一看 {% static %} 模板標(biāo)簽在頁(yè)面渲染后究竟被替換成了什么樣的值贮折。例如可以看到
正確引入了靜態(tài)文件后樣式顯示正常了裤翩。
修改模板
目前看到的只是模板中預(yù)先填充的一些數(shù)據(jù),我們得讓它顯示從數(shù)據(jù)庫(kù)中獲取的文章數(shù)據(jù)调榄。下面來(lái)稍微改造一下模板:
在模板 index.html 中你會(huì)找到一系列 article 標(biāo)簽:
這里面包裹的內(nèi)容顯示的就是文章數(shù)據(jù)了踊赠。我們前面在視圖函數(shù) index 里給模板傳了一個(gè)post_list變量,它里面包含著從數(shù)據(jù)庫(kù)中取出的文章列表數(shù)據(jù)每庆。就像 Python 一樣筐带,可以在模板中循環(huán)這個(gè)列表,把文章一篇篇循環(huán)出來(lái)扣孟,然后一篇篇顯示文章的數(shù)據(jù)烫堤。要在模板中使用循環(huán),需要使用到前面提到的模板標(biāo)簽,這次使用 {% for %} 模板標(biāo)簽鸽斟。將 index.html 中多余的 article 標(biāo)簽刪掉拔创,只留下一個(gè) article 標(biāo)簽,然后寫上下列代碼:
可以看到語(yǔ)法和 Python 的 for 循環(huán)類似富蓄,只是被 {% %} 這樣一個(gè)模板標(biāo)簽符號(hào)包裹著剩燥。{% empty %} 的作用是當(dāng)post_list為空,即數(shù)據(jù)庫(kù)里沒(méi)有文章時(shí)顯示 {% empty %} 下面的內(nèi)容立倍,最后我們用 {% endfor %} 告訴 Django 循環(huán)在這里結(jié)束了灭红。
你可能不太理解模板中的post和post_list是什么。post_list是一個(gè)QuerySet(類似于一個(gè)列表的數(shù)據(jù)結(jié)構(gòu))口注,其中每一項(xiàng)都是之前定義在 blog\models.py 中的 Post 類的實(shí)例变擒,且每個(gè)實(shí)例分別對(duì)應(yīng)著數(shù)據(jù)庫(kù)中每篇文章的記錄。因此我們循環(huán)遍歷post_list寝志,每一次遍歷的結(jié)果都保存在post變量里娇斑。所以使用模板變量來(lái)顯示post的屬性值。例如這里的{{ post.pk }}(pk 是 primary key 的縮寫材部,即 post 對(duì)應(yīng)于數(shù)據(jù)庫(kù)中記錄的 id 值毫缆,該屬性盡管我們沒(méi)有顯示定義,但是 Django 會(huì)自動(dòng)為我們添加)乐导。
現(xiàn)在可以在循環(huán)體內(nèi)通過(guò)post變量訪問(wèn)單篇文章的數(shù)據(jù)了苦丁。分析 article 標(biāo)簽里面的 HTML 內(nèi)容,h1 顯示的是文章的標(biāo)題物臂,把標(biāo)題替換成post的title屬性值旺拉。注意要把它包裹在模板變量里,因?yàn)樗罱K要被替換成實(shí)際的 title 值鹦聪。
下面這 5 個(gè) span 標(biāo)簽里分別顯示了分類(category)账阻、文章發(fā)布時(shí)間、文章作者泽本、評(píng)論數(shù)淘太、閱讀量。再次替換掉一些數(shù)據(jù)规丽,由于評(píng)論數(shù)和閱讀量暫時(shí)沒(méi)法替換蒲牧,因此先留著,我們?cè)谥髮?shí)現(xiàn)了這些功能后再來(lái)修改它赌莺,目前只替換分類冰抢、文章發(fā)布時(shí)間、文章作者:
這里 p 標(biāo)簽里顯示的是摘要艘狭,替換成post的摘要:
再次訪問(wèn)首頁(yè)挎扰,它顯示:暫時(shí)還沒(méi)有發(fā)布的文章翠订!做了這么多工作,但是數(shù)據(jù)庫(kù)中其實(shí)還沒(méi)有任何數(shù)據(jù)呀遵倦!接下來(lái)就實(shí)際寫幾篇文章保存到數(shù)據(jù)庫(kù)里尽超,看看顯示的效果究竟如何。