通过前四周的时间我们开发了一个简单的个人 Blog,本周我们将实现 blog 的标签云和文章按时间自动归档功能。
(此前四期教程请点击公众号菜单中的“Web开发”查看。)
标签云与文章归档在 Blog 中也是比较常见的功能,标签云显示每篇文章的标签,文章归档显示某个时间段内的发表的文章,就像这样:
下面我们来为我们的 Blog 添加类似的功能,最终会为我们的个人 blog 实现类似于下面这样的效果:
标签有点类似于分类,只是分类由于是多对一的关系(我们规定一篇文章只有一个分类,而一个分类下可以有多篇文章),因此在我们的 model 中使用的是 ForeignKeyField 。我们规定一篇文章可以打多个标签,并且一个标签下可能会有多篇文章,是多对多的关系,因此需要使用到 ManyToManyField,其它的实现则和 Category(分类)十分相似。首先修改我们的 model 文件,为标签(tag)新建一个数据库 model,并在文章(Article)中指定它们多对多的关系:
类似于 CategoryView,点击某个标签可以获取该标签下的全部文章,对应的视图函数:
模板文件稍微小变了一下,添加了显示标签的区域(由于模板文件代码比较多,具体请参见 github 项目中 blog/templates/blog/index.html 下的模板文件)。
同时 IndexView 里也别忘了把 tag 加到 context 中,以便在模板中渲染显示:
配置好 url :
文章归档方面,我们实现下面的需求:
在首页会显示已发表文章对应的年份列表,点击相应年份会展开该年年份下对应的月份列表,像这样:
实现思路大概如下:Django 的 ORM 为我们提供一个 datetimes 函数 ( datetimes 函数用法 ),可以选出数据库中某个 model 对应的全部已去重的时间,并且可以任意指定精度。例如,我们想选出全部文章对应的发表时间,精确到月份:
date_list = Article.objects.datetimes('created_time', 'month', order='DESC')
created_time 是 Article model 中文章发表时间,对应的是 DatetimeField( datetimes 函数也只能用于DatetimeField ),month 即精确到月,精确到年指定为 year,天则指定为 day 即可。DESC 表示降序排列,默认是升序排列。
例如有如下的一系列发表时间:
2009-01-02
2009-01-05
2009-02-02
2010-05-04
2011-06-04
2011-06-07
则得到的结果将是精确到月份去重后的结果:
2009-01
2009-02
2010-05
2011-06
这正是我们期望的结果。
以这个函数为基础,接下来我们使用 Django 的一点高级技巧(自定义 Manager)来实现完整的功能。
什么是 Manager(管理器)?Manager 可以看成是一个 model 的管理器,很多从数据库中获取 model 数据的方法都定义在这个类里,比如我们经常用的 Article.objects.all()
,Article.objects.filter()
,这里的 objects 就是一个 Manager 的实例,django 为每一个 model 都指定了一个默认的 Manager ,名字叫做 objects。但现在 Manager 中一些默认的方法无法满足我们的需求了,因此我们拓展一下 Manager 的功能,为其添加一个归档(archive)方法,拓展一个类的最佳方式就是继承它:
自定义了 Manger 后需要在 model 中显示地指定它:
blog/models.pyclass Article(models.model): ... # 仍然使用默认的 objects 作为 manager 的名字 objects = ArticleManager() ...
现在在视图函数中就可以调用了:
现在我们的时间归档列表格式是这样的:
[(2012,[09,02,01]),(2011,[12,10,06,01]),…]
因此在模板中我们可以这样循环以实现我们预初的设计:
使用一些 bootstrap 的组件即可实现上图一样的效果了。
完整的模板请参考 github 的 blog/templates/blog/index.html 模板文件。
最后一件事就是实现点击相应的时间后显示该时间下的全部已发表文章列表了,实现思路即通过 url 把对应的年份和月份传给视图函数,视图函数通过年份和月份过滤所需文章,然后再模板渲染即可,实现和 category 与 tag 的方式十分类似:
url:
templates:
我们的个人 blog 基本已经成型了!首页展示文章列表、标签云、文章归档、分类,文章 markdown 语法标记,代码高亮显示,利用 django 后台,我们可以使用它来写 blog 文章了,你可以先尝试着找一个部署教程把 blog 部署上线。当然我们接下来也会出如何部署的教程,敬请期待。下一周我们将实现评论功能,允许用户对我们发表的文章进行评论。为了学习,我们将不使用第三方 app,而是重新发明轮子。
django学习小组是一个促进 django 新手互相学习、互相帮助的组织。小组在一边学习 django 的同时将一起完成几个项目,包括:
一个简单的 django 博客,用于发布小组每周的学习和开发文档;
django中国社区,为国内的 django 开发者们提供一个长期维护的 django 社区;
联系客服