摘要:我們的博客側(cè)邊欄有四項(xiàng)內(nèi)容最新文章歸檔分類和標(biāo)簽云。更好的解決方案是直接在模板中獲取,為此,我們使用的一個(gè)新技術(shù)自定義模板標(biāo)簽來完成任務(wù)。注意要在使用任何下的模板標(biāo)簽以前導(dǎo)入它。在頁(yè)面?zhèn)冗厵谑褂米远x模板標(biāo)簽追夢(mèng)人物的博客的評(píng)論區(qū)留言。
我們的博客側(cè)邊欄有四項(xiàng)內(nèi)容:最新文章、歸檔、分類和標(biāo)簽云。這些內(nèi)容相對(duì)比較固定,且在各個(gè)頁(yè)面都會(huì)顯示,如果像文章列表或者文章詳情一樣,從視圖函數(shù)中獲取然后傳遞給模板,則每個(gè)頁(yè)面對(duì)應(yīng)的視圖函數(shù)里都要寫一段獲取這些內(nèi)容的代碼,這會(huì)導(dǎo)致很多重復(fù)代碼。更好的解決方案是直接在模板中獲取,為此,我們使用 Django 的一個(gè)新技術(shù):自定義模板標(biāo)簽來完成任務(wù)。
使用模板標(biāo)簽的解決思路我們前面已經(jīng)接觸過一些 Django 內(nèi)置的模板標(biāo)簽,比如比較簡(jiǎn)單的 {% static %} 模板標(biāo)簽,這個(gè)標(biāo)簽幫助我們?cè)谀0逯幸腱o態(tài)文件。還有比較復(fù)雜的如 {% for %} {% endfor%} 標(biāo)簽。這里 我們希望自己定義一個(gè)模板標(biāo)簽,例如名為 get_recent_posts 的模板標(biāo)簽,它可以這樣工作:我們只要在模板中寫入 {% get_recent_posts as recent_post_list %},那么模板中就會(huì)有一個(gè)從數(shù)據(jù)庫(kù)獲取的最新文章列表,并通過 as 語(yǔ)句保存到 recent_post_list 模板變量里。這樣我們就可以通過 {% for %} {% endfor%} 模板標(biāo)簽來循環(huán)這個(gè)變量,顯示最新文章列表了,這和我們?cè)诰帉懖┛褪醉?yè)面視圖函數(shù)是類似的。首頁(yè)視圖函數(shù)中從數(shù)據(jù)庫(kù)獲取文章列表并保存到 post_list 變量,然后把這個(gè) post_list 變量傳給模板,模板使用 for 模板標(biāo)簽循環(huán)這個(gè)文章列表變量,從而展示一篇篇文章。這里唯一的不同是我們從數(shù)據(jù)庫(kù)獲取文章列表的操作不是在視圖函數(shù)中進(jìn)行,而是在模板中通過自定義的 {% get_recent_posts %} 模板標(biāo)簽進(jìn)行。
以上就是解決思路,但模板標(biāo)簽不是我們隨意寫的,必須遵循 Django 的規(guī)范我們才能在 Django 的模板系統(tǒng)中使用自定義的模板標(biāo)簽,下面我們就依照這些規(guī)范來實(shí)現(xiàn)我們的需求。
模板標(biāo)簽?zāi)夸浗Y(jié)構(gòu)首先在我們的 blog 應(yīng)用下創(chuàng)建一個(gè) templatetags 文件夾。然后在這個(gè)文件夾下創(chuàng)建一個(gè) __init__.py 文件,使這個(gè)文件夾成為一個(gè) Python 包,之后在 templatetags 目錄下創(chuàng)建一個(gè) blog_tags.py 文件,這個(gè)文件存放自定義的模板標(biāo)簽代碼。
此時(shí)你的目錄結(jié)構(gòu)應(yīng)該是這樣的:
blog __init__.py admin.py apps.py migrations __init__.py models.py static templatetags __init__.py blog_tags.py tests.py views.py編寫模板標(biāo)簽代碼
接下來就是編寫各個(gè)模板標(biāo)簽的代碼了,自定義模板標(biāo)簽代碼寫在 blog_tags.py 文件中。其實(shí)模板標(biāo)簽本質(zhì)上就是一個(gè) Python 函數(shù),因此按照 Python 函數(shù)的思路來編寫模板標(biāo)簽的代碼就可以了,并沒有任何新奇的東西或者需要新學(xué)習(xí)的知識(shí)在里面。
最新文章模板標(biāo)簽打開 blog_tags.py 文件,開始寫我們的最新文章模板標(biāo)簽。
blog/templatetags/blog_tags.py from ..models import Post def get_recent_posts(num=5): return Post.objects.all().order_by("-created_time")[:num]
這個(gè)函數(shù)的功能是獲取數(shù)據(jù)庫(kù)中前 num 篇文章,這里 num 默認(rèn)為 5。函數(shù)就這么簡(jiǎn)單,但目前它還只是一個(gè)純 Python 函數(shù),Django 在模板中還不知道該如何使用它。為了能夠通過 {% get_recent_posts %} 的語(yǔ)法在模板中調(diào)用這個(gè)函數(shù),必須按照 Django 的規(guī)定注冊(cè)這個(gè)函數(shù)為模板標(biāo)簽,方法如下:
blog/templatetags/blog_tags.py from django import template from ..models import Post register = template.Library() @register.simple_tag def get_recent_posts(num=5): return Post.objects.all().order_by("-created_time")[:num]
這里我們首先導(dǎo)入 template 這個(gè)模塊,然后實(shí)例化了一個(gè) template.Library 類,并將函數(shù) get_recent_posts 裝飾為 register.simple_tag。這樣就可以在模板中使用語(yǔ)法 {% get_recent_posts %} 調(diào)用這個(gè)函數(shù)了。
注意 Django 1.9 后才支持 simple_tag 模板標(biāo)簽,如果你使用的 Django 版本小于 1.9,你將得到一個(gè)錯(cuò)誤。Django 1.9 以前的版本如何自定義模板標(biāo)簽這里不再贅述。
歸檔模板標(biāo)簽和最新文章模板標(biāo)簽一樣,先寫好函數(shù),然后將函數(shù)注冊(cè)為模板標(biāo)簽即可。
blog/templatetags/blog_tags.py @register.simple_tag def archives(): return Post.objects.dates("created_time", "month", order="DESC")
這里 dates 方法會(huì)返回一個(gè)列表,列表中的元素為每一篇文章(Post)的創(chuàng)建時(shí)間,且是 Python 的 date 對(duì)象,精確到月份,降序排列。接受的三個(gè)參數(shù)值表明了這些含義,一個(gè)是 created_time ,即 Post 的創(chuàng)建時(shí)間,month 是精度,order="DESC" 表明降序排列(即離當(dāng)前越近的時(shí)間越排在前面)。例如我們寫了 3 篇文章,分別發(fā)布于 2017 年 2 月 21 日、2017 年 3 月 25 日、2017 年 3 月 28 日,那么 dates 函數(shù)將返回 2017 年 3 月 和 2017 年 2 月這樣一個(gè)時(shí)間列表,且降序排列,從而幫助我們實(shí)現(xiàn)按月歸檔的目的。
分類模板標(biāo)簽過程還是一樣,先寫好函數(shù),然后將函數(shù)注冊(cè)為模板標(biāo)簽。注意分類模板標(biāo)簽函數(shù)中使用到了 Category 類,其定義在 blog.models.py 文件中,使用前記得先導(dǎo)入它,否則會(huì)報(bào)錯(cuò)。
blog/templatetags/blog_tags.py from ..models import Post, Category @register.simple_tag def get_categories(): # 別忘了在頂部引入 Category 類 return Category.objects.all()
盡管側(cè)邊欄有 4 項(xiàng)內(nèi)容(還有一個(gè)標(biāo)簽云),但是這里我們只實(shí)現(xiàn)最新文章、歸檔和分類數(shù)據(jù)的顯示,還有一個(gè)標(biāo)簽云沒有實(shí)現(xiàn)。因?yàn)闃?biāo)簽云的實(shí)現(xiàn)稍有一點(diǎn)不同,所以將在接下來的教程中專門介紹。這里你也可以嘗試著自己解決,如果遇到問題,可以通過官方文檔或者搜索引擎求助。獨(dú)立思考并尋求解決方案以及善用搜索引擎是一個(gè)開發(fā)者必須培養(yǎng)的能力,只有這樣你才能成為一個(gè)獨(dú)立的開發(fā)者,獨(dú)立地解決別人可能從來沒有遇到過的問題。
使用自定義的模板標(biāo)簽打開 base.html,為了使用模板標(biāo)簽,我們首先需要在模板中導(dǎo)入存放這些模板標(biāo)簽的模塊,這里是 blog_tags.py 模塊。當(dāng)時(shí)我們?yōu)榱耸褂?static 模板標(biāo)簽時(shí)曾經(jīng)導(dǎo)入過 {% load staticfiles %},這次在 {% load staticfiles %} 下再導(dǎo)入 blog_tags:
templates/base.html {% load staticfiles %} {% load blog_tags %} ...
然后找到最新文章列表處,把里面的列表修改一下:
templates/base.html
這里我們通過使用 get_recent_posts 模板標(biāo)簽獲取到最新文章列表,然后我們通過 as 語(yǔ)法(Django 模板系統(tǒng)的語(yǔ)法)將獲取的文章列表保存進(jìn)了 recent_post_list 模板變量中,之后就可以通過 for 循環(huán)來循環(huán)顯示文章列表數(shù)據(jù)了,這和我們?cè)趯懯醉?yè)視圖時(shí)是一樣的。
然后是歸檔部分:
templates/base.html
同樣,這里我們調(diào)用 archives 模板標(biāo)簽自動(dòng)獲取一個(gè)已發(fā)表文章的日期列表,精確到月份,降序排列,然后通過 as 語(yǔ)法將其保存在 date_list 模板變量里。由于日期列表中的元素為 Python 的 date 對(duì)象,因此可以通過其 year 和 month 屬性分別獲取年和月的信息,{{ date.year }} 年 {{ date.month }} 月 反應(yīng)了這個(gè)事實(shí)。
分類部分也一樣:
(13) 顯示的是該分類下的文章數(shù)目,這個(gè)特性會(huì)在接下來的教程中講解如何實(shí)現(xiàn),目前暫時(shí)用占位數(shù)據(jù)代替吧。
現(xiàn)在運(yùn)行開發(fā)服務(wù)器,可以看到側(cè)邊欄顯示的數(shù)據(jù)已經(jīng)不再是之前的占位數(shù)據(jù),而是我們保存在數(shù)據(jù)庫(kù)中的數(shù)據(jù)了。
注意:如果你按照教程的步驟做完后發(fā)現(xiàn)報(bào)錯(cuò),請(qǐng)按以下順序檢查。
檢查目錄結(jié)構(gòu)是否正確。確保 templatetags 位于 blog 目錄下,且目錄名必須為 templatetags。具體請(qǐng)對(duì)照上文給出的目錄結(jié)構(gòu)。
確保 templatetags 目錄下有 __init__.py 文件。
確保使用的 Django 版本不小于 1.9。
確保通過 register = template.Library() 和 @register.simple_tag 裝飾器將函數(shù)裝飾為一個(gè)模板標(biāo)簽。
確保在使用模板標(biāo)簽以前導(dǎo)入了 blog_tags,即 {% load blog_tags %}。注意要在使用任何 blog_tags 下的模板標(biāo)簽以前導(dǎo)入它。
確保模板標(biāo)簽的語(yǔ)法使用正確,即 {% load blog_tags %},注意 { 和 % 以及 % 和 } 之間沒有任何空格。
總結(jié)本章節(jié)的代碼位于:Step10: side bar。
如果遇到問題,請(qǐng)通過下面的方式尋求幫助。
在 頁(yè)面?zhèn)冗厵冢菏褂米远x模板標(biāo)簽 - 追夢(mèng)人物的博客 的評(píng)論區(qū)留言。
將問題的詳細(xì)描述通過郵件發(fā)送到 [email protected],一般會(huì)在 24 小時(shí)內(nèi)回復(fù)。
更多Django 教程,請(qǐng)?jiān)L問 追夢(mèng)人物的博客。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/44395.html
摘要:側(cè)邊欄已經(jīng)正確地顯示了最新文章列表歸檔分類等信息。重啟一下開發(fā)服務(wù)器,再次測(cè)試,發(fā)現(xiàn)可以顯示歸檔下的文章列表了。在分類與歸檔追夢(mèng)人物的博客的評(píng)論區(qū)留言。將問題的詳細(xì)描述通過郵件發(fā)送到,一般會(huì)在小時(shí)內(nèi)回復(fù)。 側(cè)邊欄已經(jīng)正確地顯示了最新文章列表、歸檔、分類等信息?,F(xiàn)在來完善歸檔和分類功能,當(dāng)用戶點(diǎn)擊歸檔下的某個(gè)日期或者分類下的某個(gè)分類時(shí),跳轉(zhuǎn)到文章列表頁(yè)面,顯示該日期或者分類下的全部文章。...
摘要:本章集中介紹四個(gè)重要的小功能回到頂部浮動(dòng)按鈕矢量圖標(biāo)頁(yè)腳沉底和粘性側(cè)邊欄。因?yàn)槲覀兿朐谌径紦碛羞@個(gè)按鈕,所以將剛寫好的模塊引用到中在后面引入注意模塊用到了,因此要在后面引入。 本章集中介紹四個(gè)重要的小功能:回到頂部浮動(dòng)按鈕、矢量圖標(biāo)、頁(yè)腳沉底和粘性側(cè)邊欄。 這幾個(gè)功能與Django基本沒啥關(guān)系,更多的是前端知識(shí),但是對(duì)博客網(wǎng)站都很重要,問的讀者也比較多,因此也集中講一下好了。 回到頂...
摘要:對(duì)文章詳情視圖而言,每篇文章對(duì)應(yīng)著不同的。在博客文章詳情頁(yè)追夢(mèng)人物的博客的評(píng)論區(qū)留言。將問題的詳細(xì)描述通過郵件發(fā)送到,一般會(huì)在小時(shí)內(nèi)回復(fù)。更多教程,請(qǐng)?jiān)L問追夢(mèng)人物的博客。 首頁(yè)展示的是所有文章的列表,當(dāng)用戶看到感興趣的文章時(shí),他點(diǎn)擊文章的標(biāo)題或者繼續(xù)閱讀的按鈕,應(yīng)該跳轉(zhuǎn)到文章的詳情頁(yè)面來閱讀文章的詳細(xì)內(nèi)容?,F(xiàn)在讓我們來開發(fā)博客的詳情頁(yè)面,有了前面的基礎(chǔ),開發(fā)流程都是一樣的了:首先配置 ...
摘要:我選擇的是萬(wàn)網(wǎng),阿里下面的。然后在主題配置文件下添加主題配置文件中添加自定義樣式不得不說還是很人性化的,你可以個(gè)性化定制你的網(wǎng)站,你所有的改動(dòng)需要放在主題文件的文件中,會(huì) 前言 本篇文章是在已經(jīng)搭建好gitpage+hexo的博客的前提下(不懂怎么搭建的可以參考我的另一篇博文:了解githubPages+hexo搭建博客的原理 或者利用Gitpage+hexo開發(fā)自己的博客,這兩篇博文...
摘要:我選擇的是萬(wàn)網(wǎng),阿里下面的。然后在主題配置文件下添加主題配置文件中添加自定義樣式不得不說還是很人性化的,你可以個(gè)性化定制你的網(wǎng)站,你所有的改動(dòng)需要放在主題文件的文件中,會(huì) 前言 本篇文章是在已經(jīng)搭建好gitpage+hexo的博客的前提下(不懂怎么搭建的可以參考我的另一篇博文:了解githubPages+hexo搭建博客的原理 或者利用Gitpage+hexo開發(fā)自己的博客,這兩篇博文...
閱讀 1096·2021-11-16 11:44
閱讀 1377·2019-08-30 13:12
閱讀 2418·2019-08-29 16:05
閱讀 3082·2019-08-28 18:29
閱讀 918·2019-08-26 13:41
閱讀 3238·2019-08-26 13:34
閱讀 2607·2019-08-26 10:35
閱讀 942·2019-08-26 10:28