Django学习笔记三:页面侧边栏最新文章,文章归档,分类,标签云的实现
前言
学习资源链接:http://zmrenwu.com/category/django-blog-tutorial/ 这篇文章记录了我在学习过程中掌握的知识点以及深入的理解与认识。
运行效果

(箭头 == 点击)
根据效果图可以看出,我们需要实现的功能是将内容填充到各个侧边栏对应的内容下面,并实现对应的跳转功能。
首先需要在blog应用中创建一个templatetags文件夹,并声明该文件夹为Python包。接着,在这个 templatetags 文件夹下建立 init.py 文件,并在里面声明该文件夹为Python包。同时,在同一个目录中还需要建立 blog_tags.py 文件夹来存放用于存储自定义的模板标签。
最新文章
思路:首先需要从数据库中提取前三位的文章。然后在模板index.html和detail.html中进行页面展示。当前面临的问题包括两方面:一是如何从数据库中提取前三位的文章;二是如何在模板index.html和detail.html中实现页面展示。
获取
使用Article.objects.all()从数据库中获取所有文章数据形成一个列表,在通过切片操作提取出前三篇文章。
templatetags/blog_tags.py
def get_recent_article(num=3):
return Article.objects.all().order_by('-created_time')[:num]
调用显示在模板
在编写代码时,请注意使用{% get_recent_article as recent_post_list %}这个模板标签来获取并存储文章列表到recent_post_list变量中。随后,在循环结构中遍历这些数据。 在编写代码时首先进行注册步骤以使该方法能够正常工作。
templatetags/blog_tags.py
from django import template #导入template模块
register = template.Library()
#实例化template.Library()类
@register.simple_tag
#将函数装饰为register.simple_tag
def get_recent_article(num=3):
return Article.objects.all().order_by('-created_time')[:num]
修改detail.html和index.html模板:
templates/*.detail
{% load blog_tags %}
......
<div class="widget widget-recent-posts">
<h3 class="widget-title">最新文章</h3>
{% get_recent_article as recent_post_list %}
<ul>
{% for post in recent_post_list %}
<li>
<a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
</li>
{% empty %}
暂无文章!
{% endfor %}
</ul>
</div>
......
打开浏览器后输入本地服务器地址即可看到我们的文章,并且这些文章会被自动添加到最新文章列表下方的位置;同时点击任何一篇文章标题即可跳转至详细内容页面。
打开浏览器后输入本地服务器地址即可看到我们的文章,并且这些文章会被自动添加到最新文章列表下方的位置;同时点击任何一篇文章标题即可跳转至详细内容页面。
文章归档
思路与现有最新文章高度相似;然而,在具体操作上存在差异:我们数据库中获取的信息是每篇文章单独的时间戳;而通过点击归档时间链接可以直接访问到对应时间段内的所有文章内容。
获取时间部分 :
templatetags/blog_tags.py
@register.simple_tag
def archives():
#month是精度,精确到月
return Article.objects.dates('created_time','month',order='DESC')
获取某个时间下的所有文章
使用filter方法根据条件过滤。
blog/views.py
def archives(request, year, month):
#注意created_time__year后面是两个下划线
article_list = Article.objects.filter(created_time__year=year,created_time__month=month).order_by('-created_time')
return render(request, 'index.html', context={'article_list':article_list})
绑定视图和url
blog/urls.py
url(r'^archives/(?P<year>[0-9]{4})/(?P<month>[0-9]{1,2})/$',views.archives, name='archives'),
修改detail.html和index.html模板
templates/*.detail
<div class="widget widget-archives">
<h3 class="widget-title">文章归档</h3>
{% archives as date_list %}
<ul>
{% for date in date_list %}
<li>
<a href="{% url 'blog:archives' date.year date.month %}">{{ date.year }}年 {{ date.month }}月</a>
</li>
{% empty %}
暂无归档!
{% endfor %}
</ul>
</div>
分类
与文章归档相似的是,在Django中可以通过 annotate 方法来实现这一功能。一个区别在于我们需要统计每个分类下有多少篇文章,在之前的章节中我们已经了解过通过 Django 模型管理器 objects 来进行数据获取的基本方法。例如获取所有分类列表的方式是:
Category.objects.all()
获取一个名为test的分类,获取方法:
Category.objects.get(name='test')
模型管理器objects除了all和get方法之外还有一个annotate方法可以帮助我们完成统计分类下的文章数量功能
获取分类部分(包含统计数量) :
templatetags/blog_tags.py
@register.simple_tag
def get_categories():
#统计数量 Category_list=Category.objects.annotate(num_article = Count('article'))
return Category_list
获取某个分类下的所有文章
使用filter方法根据条件过滤。
blog/views.py
def category(request,id):
cate = get_object_or_404(Category,id=id)
article_list = Article.objects.filter(category=cate).order_by('-created_time')
return render(request, 'index.html', context={'article_list':article_list})
绑定视图和url
blog/urls.py
url(r'^category/(?P<id>[0-9]+)/$',views.category, name='category'),,
修改detail.html和index.html模板
templates/*.detail
<div class="widget widget-category">
<h3 class="widget-title">分类</h3>
{% get_categories as category_list %}
<ul>
{% for category in category_list %}
<li>
<a href="{% url 'blog:category' category.id %}">{{ category.name }}({{ category.num_article}})</span></a>
</li>
{% empty %}
暂无归档!
{% endfor %}
</ul>
</div>
到现在页面侧边栏的三项功能啦。
标签云
标签云功能和分类思路和做法完全一样,就不详述啦。
总结
页面侧边栏的实现主要依赖于Django的模板标签体系。在模型管理器object中提供了get()和all()方法用于数据检索,并通过统计量 annotate 方法获取每个分类下的文章数据。
学习到这里让我突然意识到之前的方法是多么笨拙与不足。”
