Diango博客--17.統計各個分類和標簽下的文章數

文章目錄

    • 0.思路引導
    • 1.Model 回顧
    • 2.數據庫數據聚合
    • 3.使用 Annotate
    • 4.在模板中引用新增的屬性

0.思路引導

在我們的博客側邊欄有分類列表和標簽列表,顯示博客已有的全部文章分類。現在想在分類名和標簽名后顯示該分類或者標簽下有多少篇文章,該怎么做呢?最優雅的方式就是使用 django 的 annotate 方法。

1.Model 回顧

回顧一下我們的 model 代碼,django 博客有一個 Post 和 Category 模型,分別表示文章和分類:

文件位置:blog/models.py


class Post(models.Model):title = models.CharField('標題', max_length=70)body = models.TextField('正文')category = models.ForeignKey(Category, verbose_name='分類', on_delete=models.CASCADE)# 其它屬性...def __str__(self):return self.titleclass Category(models.Model):name = models.CharField('分類名', max_length=100)

我們知道從數據庫取數據都是使用模型管理器 objects 的方法實現的。比如獲取全部分類是:Category.objects.all() ,假設有一個名為 test 的分類,那么獲取該分類的方法是:Category.objects.get(name=‘test’) 。

objects 除了 all、get 等方法外,還有很多操作數據庫的方法,而其中有一個 annotate 方法,該方法可以幫我們實現本文所關注的統計分類下的文章數量的功能。

2.數據庫數據聚合

annotate 方法在底層調用了數據庫的數據聚合函數,下面使用一個實際的數據庫表來幫助我們理解 annotate 方法的工作原理。

在 Post 模型中我們通過 ForeignKey 把 Post 和 Category 關聯了起來,這時候它們的數據庫表結構就像下面這樣:

Post 表:
在這里插入圖片描述Category 表:

在這里插入圖片描述
1)當 Django 要查詢某篇 post 對應的分類時,比如 post 1,首先查詢到它分類的 id 為 1,然后 Django 再去 Category 表找到 id 為 1 的那一行,這一行就是 post 1 對應的分類。

2)反過來,如果要查詢 category 1 對應的全部文章呢?category 1 在 Category 表中對應的 id 是 1,Django 就在 Post 表中搜索哪些行的 category_id 為 1,發現前 3 行都是,把這些行取出來就是 category 1 下的全部文章了。

3)同理,這里 annotate 做的事情就是把全部 Category 取出來,然后去 Post 查詢每一個 Category 對應的文章,查詢完成后只需算一下每個 category id 對應有多少行記錄,這樣就可以統計出每個 Category 下有多少篇文章了。

4)把這個統計數字保存到每一條 Category 的記錄就可以了(當然并非保存到數據庫,在 Django ORM 中是保存到 Category 的實例的屬性中,每個實例對應一條記錄)。

3.使用 Annotate

以上是原理方面的分析,具體到 Django 中該如何用呢?在我們的博客中,獲取側邊欄的分類列表的方法寫在模板標簽 get_categories 里,因此我們修改一下這個函數,具體代碼如下:

文件位置:blog/templatetags/blog_extras.py

from django.db.models.aggregates import Count
from blog.models import Category@register.inclusion_tag('blog/inclusions/_categories.html', takes_context=True)
def show_categories(context):category_list = Category.objects.annotate(num_posts=Count('post')).filter(num_posts__gt=0)return {'category_list': category_list,}

1)這個 Category.objects.annotate 方法和 Category.objects.all 有點類似,它會返回數據庫中全部 Category 的記錄,但同時它還會做一些額外的事情,在這里我們希望它做的額外事情就是去統計返回的 Category 記錄的集合中每條記錄下的文章數。

2)代碼中的 Count 方法為我們做了這個事,它接收一個和 Categoty 相關聯的模型參數名(這里是 Post,通過 ForeignKey 關聯的),然后它便會統計 Category 記錄的集合中每條記錄下的與之關聯的 Post 記錄的行數,也就是文章數,最后把這個值保存到 num_posts 屬性中。

3)此外,我們還對結果集做了一個過濾,使用 filter 方法把 num_posts 的值小于 1 的分類過濾掉。因為 num_posts 的值小于 1 表示該分類下沒有文章,沒有文章的分類我們不希望它在頁面中顯示。

同理,tags 也可以做同樣的操作。

@register.inclusion_tag('blog/inclusions/_tags.html', takes_context=True)
def show_tags(context):tag_list = Tag.objects.annotate(num_posts=Count('post')).filter(num_posts__gt=0)return {'tag_list': tag_list,}

4.在模板中引用新增的屬性

現在在 Category 和 Tag 列表中每一項都新增了一個 num_posts 屬性記錄該 Category 下的文章數量,我們就可以在模板中引用這個屬性來顯示分類下的文章數量了。

文件位置:templates/blog/inclusions/_categories.html

<div class="widget widget-category"><h3 class="widget-title">分類</h3><ul>{% for category in category_list %}<li><a href="{% url 'blog:category' category.pk %}">{{ category.name }} <span class="post-count">({{ category.num_posts }})</span></a></li>{% empty %}暫無分類!{% endfor %}</ul>
</div>

文件位置:templates/blog/inclusions/_tags.html

<div class="widget widget-tag-cloud"><h3 class="widget-title">標簽云</h3><ul>{% for tag in tag_list %}<li><a href="{% url 'blog:tag' tag.pk %}">{{ tag.name }} <span class="post-count">({{ tag.num_posts }})</a></li>{% empty %}暫無標簽!{% endfor %}</ul>
</div>

也就是在模板中通過模板變量 {{ category.num_posts }}以及 {{ tag.num_posts }}顯示 num_posts 的值。

開啟開發服務器,可以看到分類名后正確地顯示了該分類下的文章數了,而沒有文章分類則不會在分類列表中出現。

效果展示如下:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452386.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452386.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452386.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HTTP協議中request報文請求方法和狀態響應碼

一個HTTP請求報文由4部分組成&#xff1a; 請求行&#xff08;request line&#xff09;請求頭部&#xff08;header&#xff09;空行請求數據下圖給出了請求報文的一般格式&#xff1a; 請求行中包括了請求方法&#xff0c;常見的請求方法有&#xff1a; GET&#xff1a;從服務…

計算機無法安裝64位操作系統,為什么我的win7旗艦版service Pack 1 64位操作系統 無法安裝(KB2670838) 這個更新...

您好&#xff01;我了解到您遇到關于這邊的問題請問無法安裝是否出現了什么錯誤代碼提示呢&#xff1f;請參考以下的步驟解決按WindowsR打開cmd里使用下面的命令關閉相關的一些服務&#xff1a;net stop wuauservnet stop cryptSvcnet stop bitsnet stop msiserver完成后&#…

bmon:一個強大的網絡帶寬監視和調試工具

bmon 是類 Unix 系統中一個基于文本&#xff0c;簡單但非常強大的 網絡監視和調試工具&#xff0c;它能抓取網絡相關統計信息并把它們以用戶友好的格式展現出來。它是一個可靠高效的帶寬監視和網速估測工具。 它能使用各種輸入模塊讀取輸入&#xff0c;并以各種輸出模式顯示輸出…

函數的調用規則(__cdecl,__stdcall,__fastcall,__pascal)

關于函數的調用規則&#xff08;調用約定&#xff09;&#xff0c;大多數時候是不需要了解的&#xff0c;但是如果需要跨語言的編程&#xff0c;比如VC寫的dll要delphi調用&#xff0c;則需要了解。 microsoft的vc默認的是__cdecl方式&#xff0c;而windows API則是__stdcall&a…

Linux 下的/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin區別

1、/bin 是所有用戶都可以訪問并執行的可執行程序。包括超級用戶及一般用戶。 供所有用戶&#xff08;包括root用戶和一般用戶&#xff09;使用的基本命令&#xff0c;主要有cat,chmod,date,cp,bash等等常用的命令。 2、/usr/bin&#xff1a;系統預裝的可執行程序&#xff0c;…

alpha測試和betal測試

如果一個軟件是為許多客戶開發的&#xff08;例如&#xff0c;向大眾公開出售的盒裝軟件產品&#xff09;&#xff0c;那么絕大多數軟件開發商都使用被稱為Alpha測試和Beta測試的過程&#xff0c;來發現那些看起來只有最終用戶才能發現的錯誤。 Alpha測試由用戶在開發者的場所進…

計算機d盤無法格式化,四種方法解決D盤無法格式化問題

不少朋友系統出現故障&#xff0c;幾乎都是選擇重裝系統的方法來解決問題。系統重裝后&#xff0c;不少朋友覺得D盤沒有什么重要的東西&#xff0c;就想將其格式化&#xff0c;可是系統出現windows無法格式該驅動器的提示&#xff0c;這是怎么回事呢&#xff1f;D盤無法格式化要…

sqlserver視圖

作用 ①簡化了操作&#xff0c;把經常使用的數據定義為視圖。 ②安全性&#xff0c;用戶只能查詢和修改能看到的數據。 ③邏輯上的獨立性&#xff0c;屏蔽了真實表的結構帶來的影響。 對視圖的修改&#xff1a;單表視圖一般用于查詢和修改&#xff0c;會改變基本表的數據&#…

非root用戶sudo_ssh免密鑰

非root用戶sudo_ssh免密鑰 目標&#xff1a;從服務器上ssh登陸后sudo免密鑰執行相應的命令 環境介紹&#xff1a; 192.168.65.128 my1-222 192.168.65.129 my2-223 192.168.65.130 web224# 步驟一&#xff1a; # 每個節點執行(不是必須&#xff0c;但是建議這樣做) cat …

復旦大學和吉大計算機考研選哪個,2016復旦大學VS吉林大學 基于排名角度的比較?...

復旦大學好還是吉林大學好首先&#xff0c;2016復旦大學好還是吉林大學好是近日問得較多的問題之一&#xff0c;小伙伴們有的從吉林大學和復旦大學的地理位置優勢角度進行分析&#xff0c;有的從吉林大學和復旦大學的強勢專業角度進行PK&#xff0c;有的甚至從吉林大學和復旦大…

Diango博客--18.使用 Fabric 自動化部署 Django 項目

文章目錄1.本地安裝 Fabric2.部署過程回顧3.完善項目配置4.修改 BASE_DIR 配置項5.設置 Supervisor 環境變量6.編寫 Fabric 腳本7.執行 Fabric 自動部署腳本1.本地安裝 Fabric $ pipenv install fabric --dev 報錯&#xff1a; An error occurred while installing django-pure…

白盒測試詳解

通常把測試數據和預期的輸出結果稱為測試用例。 &#xff08;一&#xff09;邏輯覆蓋 是對一系列測試過程的總稱&#xff0c;這組測試過程逐漸進行越來越完整的通路測試。 1.語句覆蓋 語句覆蓋的含義是&#xff0c;選擇足夠多的測試數據&#xff0c;使被測程序中每個語句至少…

git 的安裝以及使用:是一個開源的分布式版本控制系統,可以對項目進行版本管理。 早期是linux之父用來管理linux系統源代碼的(linux是和windows一樣操作系統 開源免費的操作...

## 總結 - 學會使用基本的git命令 管理源代碼- 學會去github創建倉庫 并將代碼上傳到github的倉庫 (有待完成 回家有網再push)- 了解本地的.git和服務器github的.git的關系 是兩個倉庫 一個是本地 一個是服務器 需要使用一句命令來關聯 git remote add origin 遠端的.git的地址…

自斷前程,未來80%IT工作將實現自動化

技術人員革了自己的命&#xff1f; 在上周的Structure大會上&#xff0c;硅谷著名風險投資人、億萬富翁唯諾德稱未來80%的IT工作都將被AI系統所替代。不過&#xff0c;唯諾德好像并不擔心&#xff0c;相反他補充了一句“我覺得很興奮。”唯諾德表示自己并非危言聳聽&#xff0c…

2013計算機二級試題,2013全國計算機二級上機考試試題46-100套試題

*第46 套上機考試試題一、基本操作題**請根據以下各小題的要求設計Visual Basic 應用程序(包括界面和代碼)。(1)在名稱為Form1、標題為“框架練習”的窗體上*畫一個名稱為Frame1、標題為“字體”的框架控件&#xff1b;在框架中畫兩個單選按鈕&#xff0c;名稱分別為Option1、O…

黑盒測試詳解

黑盒測試著重測試軟件功能。黑盒測試并不能取代白盒測試&#xff0c;它是與白盒測試互補的測試方法&#xff0c;它很可能發現白盒測試不易發現的其他類型的錯誤。白盒測試在測試過程的早期階段進行&#xff0c;而黑盒測試主要用于測試過程的后期。 黑盒測試力圖發現下述類型的…

linux中rpm、yum、apt-get的關系

Linux中yum和apt-get用法及區別 一般來說著名的linux系統基本上分兩大類&#xff1a; 1.RedHat系列&#xff1a;Redhat、Centos、Fedora等 2.Debian系列&#xff1a;Debian、Ubuntu等 RedHat 系列 1 常見的安裝包格式 rpm包,安裝rpm包的命令是“rpm -參數” 2 包管理工具 y…

echart事件

reference&#xff1a; https://www.w3cschool.cn/echarts_tutorial/echarts_tutorial-7o3u28yh.html var mychart echarts.init(document.getElementById(abc)); var option {....}//忽略了具體參數 mychart.on(click,function(params){console.log(params);console.log(para…

三網融合情況下,實時語音通信技術的研究

隨著技術和標準的不斷成熟,伴隨著“三網合一”的大潮,VoIP可望成為下一代電信基礎設施結構的楊心,使未來各電信業務綜合統一在IP網絡上成為可能,導致數據的融合和未來電信市場的重組,并帶來新的經濟模式和價值鏈。 Internet在全世界范圍內的快速發展和語音信號處理技術的進步,促…

計算機操作系統指導書,《計算機操作系統》實驗指導書-2015

q.num;System.out.println(\已生產第&#xff1a;\個產品!\try {Thread.currentThread().sleep(100); } catch (InterruptedException e) {e.printStackTrace(); }q.notify(); }else {try {System.out.println(\ q.wait();} catch (InterruptedException e) {e.printStackTrace…