開(kāi)啟Django博客的RSS功能的實(shí)現(xiàn)方法
作者:HelloGitHub-追夢(mèng)人物
文中所涉及的示例代碼,已同步更新到 HelloGitHub-Team 倉(cāng)庫(kù)
博客提供 RSS 訂閱應(yīng)該是標(biāo)配,這樣讀者就可以通過(guò)一些聚合閱讀工具訂閱你的博客,時(shí)時(shí)查看是否有文章更新,而不必每次都跳轉(zhuǎn)到博客上來(lái)查看?,F(xiàn)在我們就來(lái)為博客添加 RSS 訂閱功能。
RSS 簡(jiǎn)介
RSS(Really Simple Syndication)是一種描述和同步網(wǎng)站內(nèi)容的格式,它采用 XML 作為內(nèi)容傳遞的格式。簡(jiǎn)單來(lái)說(shuō)就是網(wǎng)站可以把內(nèi)容包裝成符合 RSS 標(biāo)準(zhǔn)的 XML 格式文檔。一旦網(wǎng)站內(nèi)容符合一個(gè)統(tǒng)一的規(guī)范,那么人們就可以開(kāi)發(fā)一種讀取這種規(guī)范化的 XML 文檔的工具來(lái)聚合各大網(wǎng)站的內(nèi)容。例如一個(gè)讀者可能關(guān)注了很多的博客網(wǎng)站,如果這些博客網(wǎng)站都支持 RSS 訂閱的話,他就只需要一個(gè)聚合閱讀器訂閱這些博客,就可以在聚合器工具里看到全部博客的更新內(nèi)容,而不必再分別訪問(wèn)各個(gè)博客去看有沒(méi)有內(nèi)容更新了。更多 RSS 的介紹,可參考rss (簡(jiǎn)易信息聚合)。
使用 Django Feed 類
根據(jù)以上對(duì) RSS 的介紹,我們可以發(fā)現(xiàn)關(guān)鍵的地方就是根據(jù)網(wǎng)站的內(nèi)容生成規(guī)范化的 XML 文檔,幸運(yùn)的是,Django 已經(jīng)內(nèi)置了一些生成這個(gè)文檔的方法,下面就使用這些方法來(lái)創(chuàng)建 RSS 訂閱文檔。
首先我們?cè)?blog 應(yīng)用的根目錄下(models.py 所在目錄)新建一個(gè) feeds.py 文件以存放和 RSS 功能相關(guān)的代碼。讓后在 feeds.py 中寫(xiě)入如下代碼:
blog/feeds.py
from django.contrib.syndication.views import Feed from .models import Post class AllPostsRssFeed(Feed): # 顯示在聚合閱讀器上的標(biāo)題 title = "HelloDjango-blog-tutorial" # 通過(guò)聚合閱讀器跳轉(zhuǎn)到網(wǎng)站的地址 link = "/" # 顯示在聚合閱讀器上的描述信息 description = "HelloDjango-blog-tutorial 全部文章" # 需要顯示的內(nèi)容條目 def items(self): return Post.objects.all() # 聚合器中顯示的內(nèi)容條目的標(biāo)題 def item_title(self, item): return "[%s] %s" % (item.category, item.title) # 聚合器中顯示的內(nèi)容條目的描述 def item_description(self, item): return item.body_html
代碼應(yīng)該不難理解,主要就是指定要生成的 XML 文檔內(nèi)容。各個(gè)屬性和方法的含義已在代碼中注釋,你只需把相關(guān)的內(nèi)容替換成符合你博客的描述即可。
需要注意一點(diǎn)的是這個(gè)方法:
# 聚合器中顯示的內(nèi)容條目的描述 def item_description(self, item): return item.body_html
item 是文章 (Post 模型的實(shí)例),聚合內(nèi)容的描述我們返回了 body_html 屬性的值。模型中原本使用 body 屬性存儲(chǔ)博客文章的內(nèi)容,但是這些內(nèi)容是以 Markdown 格式的,并非所有的聚合內(nèi)容閱讀器都支持 Markdown 格式的解析,因此我們返回的是已經(jīng)解析后的 HTML 格式內(nèi)容。
但 Post 模型原來(lái)并沒(méi)有 body_html 這個(gè)屬性的,那它是哪里來(lái)的呢?
回顧一下 PostDetailView 這個(gè)視圖,我們?cè)讷@取博客文章 post 的詳細(xì)內(nèi)容的視圖中,使用 markdown 這個(gè) Python 庫(kù)在解析 post.body 這個(gè)屬性的值。這個(gè)解析的過(guò)程其實(shí)在很多地方都可能用到,不應(yīng)該寫(xiě)死在 PostDetailView 這個(gè)視圖里,所以我們先將 PostDetailView 視圖的 get_object 方法解析 Markdown 內(nèi)容的過(guò)程封裝為一個(gè)函數(shù),暫且將其放在 blog/models.py 中。
blog/models.py
def generate_rich_content(value): md = markdown.Markdown( extensions=[ "markdown.extensions.extra", "markdown.extensions.codehilite", # 記得在頂部引入 TocExtension 和 slugify TocExtension(slugify=slugify), ] ) content = md.convert(value) m = re.search(r'<div class="toc">\s*<ul>(.*)</ul>\s*</div>', md.toc, re.S) toc = m.group(1) if m is not None else "" return {"content": content, "toc": toc}
解析過(guò)程和原來(lái)一樣,只是將解析得到的 HTML 內(nèi)容(content)和目錄(toc)放在一個(gè)字典里返回。
然后,我們來(lái)給 Post 模型定義幾個(gè)屬性,以便方便地獲取解析后的內(nèi)容和目錄:
blog/models.py
from django.utils.functional import cached_property class Post(models.Model): # 省略其它代碼 @property def toc(self): return self.rich_content.get("toc", "") @property def body_html(self): return self.rich_content.get("content", "") @cached_property def rich_content(self): return generate_rich_content(self.body)
首先看到 rich_content 這個(gè)方法,它返回的是 generate_rich_content 函數(shù)調(diào)用后的結(jié)果,即將 body 屬性的值經(jīng) Markdown 解析后的內(nèi)容。但要注意的是我們使用了 django 提供的 cached_property 裝飾器,這個(gè)裝飾器和 Python 內(nèi)置的 property 裝飾器功能一樣,可以將方法轉(zhuǎn)為屬性,這樣就能夠以屬性訪問(wèn)的方式獲取方法返回的值,不過(guò) cached_property 進(jìn)一步提供緩存功能,它將被裝飾方法調(diào)用返回的值緩存起來(lái),下次訪問(wèn)時(shí)將直接讀取緩存內(nèi)容,而不需重復(fù)執(zhí)行方法獲取返回結(jié)果。例如對(duì)博客文章內(nèi)容的 Markdown 解析是比較耗時(shí)的,而解析的結(jié)果可能被多次訪問(wèn),因此將其緩存起來(lái)能起到優(yōu)化作用。
為了更方便地獲取文章的 HTML 格式的內(nèi)容和目錄,我們進(jìn)一步將 generate_rich_content 返回的值放到 toc 和 body_html 兩個(gè)屬性中,這里兩個(gè)屬性都從 rich_content 中取值,cached_property 的作用就發(fā)揮出來(lái)了。
添加 URL
接下來(lái)就是指定 URL 模式,讓人們?cè)L問(wèn)這個(gè) URL 后就可以看到 Feed 生成的內(nèi)容。通常 RSS 的 URL 配置直接寫(xiě)在項(xiàng)目的 urls.py 文件里,即打開(kāi) blogproject/urls.py 文件,添加如下代碼:
blogproject/urls.py
from blog.feeds import AllPostsRssFeed urlpatterns = [ path('admin/', admin.site.urls), path('', include('blog.urls')), path('', include('comments.urls')), # 記得在頂部引入 AllPostsRssFeed path('all/rss/', AllPostsRssFeed(), name='rss'), ]
修改模板
簡(jiǎn)單修改一下 templates/base.html 模板,把 RSS 的 URL 添加到模板中:
<div class="rss"> <a href="{% url 'rss' %}" rel="external nofollow" ><span class="ion-social-rss-outline"></span> RSS 訂閱</a> </div>
此外,由于將 Markdown 解析的內(nèi)容放在了 body_html 屬性,將之前博客文章詳情模板里獲取文章內(nèi)容的代碼也做相應(yīng)調(diào)整:
templates/blog/detail.html
<div class="entry-content clearfix"> {{ post.body_html|safe }} </div>
運(yùn)行開(kāi)發(fā)服務(wù)器,在側(cè)邊欄點(diǎn)擊 RSS 訂閱的鏈接,就跳轉(zhuǎn)到 /all/rss/,你會(huì)看到這對(duì)亂碼一樣的東西,這就是生成的 RSS 標(biāo)準(zhǔn)文檔,當(dāng)然這個(gè)文檔不是給你讀的,而是給 RSS 聚合閱讀器工具讀的。
RSS 測(cè)試插件
可以在本地測(cè)試一下訂閱效果,我使用的 Chrome 瀏覽器,安裝了一個(gè) RSS Feed Reader 的應(yīng)用,如果你也使用的 Chrome 瀏覽器,可以從應(yīng)用商店添加它,然后就可以在本地測(cè)試訂閱效果了。如果是其它瀏覽器,自行查找相關(guān) RSS 閱讀插件即可。我本地測(cè)試效果如下:
可以看到訂閱成功了,訂閱界面顯示的信息就是我們?cè)?AllPostsRssFeed 類中指定的相關(guān)信息。大功告成,現(xiàn)在任何人都可以訂閱我們的博客了!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Django 博客實(shí)現(xiàn)簡(jiǎn)單的全文搜索的示例代碼
- 基于Django統(tǒng)計(jì)博客文章閱讀量
- Python使用Django實(shí)現(xiàn)博客系統(tǒng)完整版
- 使用python和Django完成博客數(shù)據(jù)庫(kù)的遷移方法
- 利用Celery實(shí)現(xiàn)Django博客PV統(tǒng)計(jì)功能詳解
- Python采用Django開(kāi)發(fā)自己的博客系統(tǒng)
- Python Django搭建網(wǎng)站流程圖解
- Django如何實(shí)現(xiàn)網(wǎng)站注冊(cè)用戶郵箱驗(yàn)證功能
- python3.6+django2.0+mysql搭建網(wǎng)站過(guò)程詳解
- 用Django寫(xiě)天氣預(yù)報(bào)查詢網(wǎng)站
- Python+Django搭建自己的blog網(wǎng)站
- 利用django創(chuàng)建一個(gè)簡(jiǎn)易的博客網(wǎng)站的示例
相關(guān)文章
python讀取測(cè)試數(shù)據(jù)的多種方式
本文主要介紹了python讀取測(cè)試數(shù)據(jù)的多種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08Python?Diagrams創(chuàng)建高質(zhì)量圖表和流程圖實(shí)例探究
Python?Diagrams是一個(gè)強(qiáng)大的Python庫(kù),使創(chuàng)建這些圖表變得簡(jiǎn)單且靈活,本文將深入介紹Python?Diagrams,包括其基本概念、安裝方法、示例代碼以及一些高級(jí)用法,以幫助大家充分利用這一工具來(lái)創(chuàng)建令人印象深刻的圖表2024-01-01在python中畫(huà)正態(tài)分布圖像的實(shí)例
今天小編就為大家分享一篇在python中畫(huà)正態(tài)分布圖像的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07Python實(shí)現(xiàn)數(shù)據(jù)庫(kù)并行讀取和寫(xiě)入實(shí)例
本篇文章主要介紹了Python實(shí)現(xiàn)數(shù)據(jù)庫(kù)并行讀取和寫(xiě)入實(shí)例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-06-06Python機(jī)器學(xué)習(xí)算法之k均值聚類(k-means)
這篇文章主要為大家詳細(xì)介紹了Python機(jī)器學(xué)習(xí)算法之k均值聚類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02python使用matplotlib庫(kù)生成隨機(jī)漫步圖
這篇文章主要為大家詳細(xì)介紹了使用Python的matplotlib庫(kù)生成隨機(jī)漫步圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08教你利用python實(shí)現(xiàn)企業(yè)微信發(fā)送消息
今天帶大家來(lái)練習(xí)python實(shí)戰(zhàn),文中對(duì)利用python實(shí)現(xiàn)企業(yè)微信發(fā)送消息作了詳細(xì)的圖文解說(shuō)及代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴很有幫助,需要的朋友可以參考下2021-05-05Python定時(shí)任務(wù)框架APScheduler安裝使用詳解
這篇文章主要介紹了Python定時(shí)任務(wù)框架APScheduler安裝使用詳解,重點(diǎn)介紹如何使用APscheduler實(shí)現(xiàn)python定時(shí)任務(wù),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)Python定時(shí)任務(wù)APScheduler相關(guān)知識(shí)感興趣的朋友一起看看吧2022-05-05