所謂分類和日期存檔其實(shí)都是一種歸檔方法位迂,區(qū)別只在于是以分類歸檔還是日期歸檔而已坡垫。
側(cè)邊欄的分類歸檔
側(cè)邊欄的分類歸檔要顯示兩個(gè)元素:分類名稱和對(duì)應(yīng)的文章數(shù)量。我們使用collections中的Counter計(jì)數(shù)器女责,用來跟蹤值出現(xiàn)了多少次樱衷。
def get_tags():
postsAll = Article.objects.annotate(num_comment=Count('id')).filter(
published_date__isnull=False)
tags = [str(p.category) for p in postsAll if str(p.category) != '']
tags_dict = Counter(tags)
return tags_dict
tags是包含所有分類的一個(gè)列表,使用Counter計(jì)數(shù)器后所得到的tags_dict是包含分類和其對(duì)應(yīng)文章數(shù)的字典店溢,鍵是分類名稱叁熔,值是文章數(shù)。
因此床牧,只要把tags_dict傳到base.html的側(cè)邊欄顯示出來就行了者疤。注意views.py里面的大多數(shù)函數(shù)都使用了base.html模板,所以它們也需要傳遞tags_dict到它們的模板中叠赦,以免出錯(cuò)或不顯示。
base.html側(cè)邊欄的設(shè)計(jì)和鏈接就不多說了革砸,這里要提一下怎么在模板里面遍歷字典除秀。因?yàn)槟0謇锩娌荒苤苯颖闅v字典,所以要通過變量替代key取value算利,參考方法:http://www.cnblogs.com/noobkey/p/5197850.html
側(cè)邊欄日期存檔
分類和日期都是文章的一個(gè)屬性册踩,因此可以用相似的方法實(shí)現(xiàn)日期存檔。但是存在幾個(gè)問題:
1效拭、日期包含年月日和時(shí)間暂吉,精確到時(shí)間(時(shí)和分)的話顯然每篇文章都是不一樣的,這樣的歸檔結(jié)果就是每個(gè)日期都只對(duì)應(yīng)一篇文章缎患,顯然是不符合要求的慕的,所以要注意歸檔時(shí)候的精度,一般到月就可以了挤渔。
2肮街、我們?cè)诜诸悮w檔中傳遞的是一個(gè)字典,字典是無序的判导,這對(duì)于分類來說無所謂嫉父,因?yàn)榉诸惷Q的順序?qū)κ褂脹]有什么影響,但日期不能無序眼刃,一般應(yīng)按照從近到遠(yuǎn)的順序排列绕辖,所以Counter結(jié)果就不能直接傳到模板顯示了,還需要排序擂红。
對(duì)于第一個(gè)問題仪际,Django 學(xué)習(xí)小組:標(biāo)簽云與文章歸檔 里面使用了datetimes函數(shù),可以選出數(shù)據(jù)庫(kù)中某個(gè)model對(duì)應(yīng)的全部已去重的時(shí)間,并且可以任意指定精度弟头。這個(gè)函數(shù)相當(dāng)于一個(gè)去重的作用吩抓,不統(tǒng)計(jì)每種日期出現(xiàn)的次數(shù),因此無法得到日期對(duì)應(yīng)的文章數(shù)赴恨。如果不需要顯示文章數(shù)的話這就夠用了疹娶,但我還是覺得有個(gè)數(shù)量更好看和人性化。所以我使用了另一種方法伦连,參考:django實(shí)現(xiàn)日期分類效果 雨饺。我的代碼是:
def date_list():
postsAll = Article.objects.annotate(num_comment=Count('id')).filter(
published_date__isnull=False).order_by('-published_date')
year_month_list = [(p.published_date.year, p.published_date.month) for p in postsAll]
year_month_dict = Counter(year_month_list)
date_list = [(key[0], key[1], year_month_dict[key]) for key in year_month_dict]
date_list.sort(reverse=True)
return date_list
也就是遍歷文章,以年和月組成元組作為元素惑淳,構(gòu)造一個(gè)列表year_month_list额港,Counter完后,把字典轉(zhuǎn)換成列表歧焦,列表元素是(year,month,num)元組移斩,最后把列表排序即可。
模板內(nèi)遍歷列表內(nèi)元組的方法是:
{% for d in date_list %}
<a href="{% url 'date_archives' y=d.0 m=d.1 %}">{{ d.0 }}年{{ d.1 }}月</a> ({{d.2}})
{% endfor %}
這里d就是列表內(nèi)的一個(gè)個(gè)元組绢馍,d.0向瓷,d.1和d.2就是元組內(nèi)元素。美化同樣不多說了舰涌。
順帶說一下猖任,我這幾個(gè)函數(shù)都不帶request參數(shù),只是普通Python函數(shù)而已瓷耙,方便功能拆分和多處調(diào)用朱躺,應(yīng)該在其他帶request的視圖函數(shù)內(nèi)調(diào)用它。
2016.10.13