资讯专栏INFORMATION COLUMN

Django 博客开发教程 10 - 页面侧边栏:使用自定义模板标签

summerpxy / 2386人阅读

摘要:我们的博客侧边栏有四项内容最新文章归档分类和标签云。更好的解决方案是直接在模板中获取,为此,我们使用的一个新技术自定义模板标签来完成任务。注意要在使用任何下的模板标签以前导入它。在页面侧边栏使用自定义模板标签追梦人物的博客的评论区留言。

我们的博客侧边栏有四项内容:最新文章、归档、分类和标签云。这些内容相对比较固定,且在各个页面都会显示,如果像文章列表或者文章详情一样,从视图函数中获取然后传递给模板,则每个页面对应的视图函数里都要写一段获取这些内容的代码,这会导致很多重复代码。更好的解决方案是直接在模板中获取,为此,我们使用 Django 的一个新技术:自定义模板标签来完成任务。

使用模板标签的解决思路

我们前面已经接触过一些 Django 内置的模板标签,比如比较简单的 {% static %} 模板标签,这个标签帮助我们在模板中引入静态文件。还有比较复杂的如 {% for %} {% endfor%} 标签。这里 我们希望自己定义一个模板标签,例如名为 get_recent_posts 的模板标签,它可以这样工作:我们只要在模板中写入 {% get_recent_posts as recent_post_list %},那么模板中就会有一个从数据库获取的最新文章列表,并通过 as 语句保存到 recent_post_list 模板变量里。这样我们就可以通过 {% for %} {% endfor%} 模板标签来循环这个变量,显示最新文章列表了,这和我们在编写博客首页面视图函数是类似的。首页视图函数中从数据库获取文章列表并保存到 post_list 变量,然后把这个 post_list 变量传给模板,模板使用 for 模板标签循环这个文章列表变量,从而展示一篇篇文章。这里唯一的不同是我们从数据库获取文章列表的操作不是在视图函数中进行,而是在模板中通过自定义的 {% get_recent_posts %} 模板标签进行。

以上就是解决思路,但模板标签不是我们随意写的,必须遵循 Django 的规范我们才能在 Django 的模板系统中使用自定义的模板标签,下面我们就依照这些规范来实现我们的需求。

模板标签目录结构

首先在我们的 blog 应用下创建一个 templatetags 文件夹。然后在这个文件夹下创建一个 __init__.py 文件,使这个文件夹成为一个 Python 包,之后在 templatetags 目录下创建一个 blog_tags.py 文件,这个文件存放自定义的模板标签代码。

此时你的目录结构应该是这样的:

blog
    __init__.py
    admin.py
    apps.py
    migrations
        __init__.py
    models.py
    static
    templatetags
        __init__.py
        blog_tags.py
    tests.py
    views.py
编写模板标签代码

接下来就是编写各个模板标签的代码了,自定义模板标签代码写在 blog_tags.py 文件中。其实模板标签本质上就是一个 Python 函数,因此按照 Python 函数的思路来编写模板标签的代码就可以了,并没有任何新奇的东西或者需要新学习的知识在里面。

最新文章模板标签

打开 blog_tags.py 文件,开始写我们的最新文章模板标签。

blog/templatetags/blog_tags.py

from ..models import Post

def get_recent_posts(num=5):
    return Post.objects.all().order_by("-created_time")[:num]

这个函数的功能是获取数据库中前 num 篇文章,这里 num 默认为 5。函数就这么简单,但目前它还只是一个纯 Python 函数,Django 在模板中还不知道该如何使用它。为了能够通过 {% get_recent_posts %} 的语法在模板中调用这个函数,必须按照 Django 的规定注册这个函数为模板标签,方法如下:

blog/templatetags/blog_tags.py

from django import template
from ..models import Post

register = template.Library()

@register.simple_tag
def get_recent_posts(num=5):
    return Post.objects.all().order_by("-created_time")[:num]

这里我们首先导入 template 这个模块,然后实例化了一个 template.Library 类,并将函数 get_recent_posts 装饰为 register.simple_tag。这样就可以在模板中使用语法 {% get_recent_posts %} 调用这个函数了。

注意 Django 1.9 后才支持 simple_tag 模板标签,如果你使用的 Django 版本小于 1.9,你将得到一个错误。Django 1.9 以前的版本如何自定义模板标签这里不再赘述。

归档模板标签

和最新文章模板标签一样,先写好函数,然后将函数注册为模板标签即可。

blog/templatetags/blog_tags.py

@register.simple_tag
def archives():
    return Post.objects.dates("created_time", "month", order="DESC")

这里 dates 方法会返回一个列表,列表中的元素为每一篇文章(Post)的创建时间,且是 Python 的 date 对象,精确到月份,降序排列。接受的三个参数值表明了这些含义,一个是 created_time ,即 Post 的创建时间,month 是精度,order="DESC" 表明降序排列(即离当前越近的时间越排在前面)。例如我们写了 3 篇文章,分别发布于 2017 年 2 月 21 日、2017 年 3 月 25 日、2017 年 3 月 28 日,那么 dates 函数将返回 2017 年 3 月 和 2017 年 2 月这样一个时间列表,且降序排列,从而帮助我们实现按月归档的目的。

分类模板标签

过程还是一样,先写好函数,然后将函数注册为模板标签。注意分类模板标签函数中使用到了 Category 类,其定义在 blog.models.py 文件中,使用前记得先导入它,否则会报错。

blog/templatetags/blog_tags.py

from ..models import Post, Category

@register.simple_tag
def get_categories():
    # 别忘了在顶部引入 Category 类
    return Category.objects.all()

尽管侧边栏有 4 项内容(还有一个标签云),但是这里我们只实现最新文章、归档和分类数据的显示,还有一个标签云没有实现。因为标签云的实现稍有一点不同,所以将在接下来的教程中专门介绍。这里你也可以尝试着自己解决,如果遇到问题,可以通过官方文档或者搜索引擎求助。独立思考并寻求解决方案以及善用搜索引擎是一个开发者必须培养的能力,只有这样你才能成为一个独立的开发者,独立地解决别人可能从来没有遇到过的问题。

使用自定义的模板标签

打开 base.html,为了使用模板标签,我们首先需要在模板中导入存放这些模板标签的模块,这里是 blog_tags.py 模块。当时我们为了使用 static 模板标签时曾经导入过 {% load staticfiles %},这次在 {% load staticfiles %} 下再导入 blog_tags:

templates/base.html

{% load staticfiles %}
{% load blog_tags %}


...

然后找到最新文章列表处,把里面的列表修改一下:

templates/base.html

最新文章

{% get_recent_posts as recent_post_list %}
    {% for post in recent_post_list %}
  • {{ post.title }}
  • {% empty %} 暂无文章! {% endfor %}

这里我们通过使用 get_recent_posts 模板标签获取到最新文章列表,然后我们通过 as 语法(Django 模板系统的语法)将获取的文章列表保存进了 recent_post_list 模板变量中,之后就可以通过 for 循环来循环显示文章列表数据了,这和我们在写首页视图时是一样的。

然后是归档部分:

templates/base.html

归档

{% archives as date_list %}

同样,这里我们调用 archives 模板标签自动获取一个已发表文章的日期列表,精确到月份,降序排列,然后通过 as 语法将其保存在 date_list 模板变量里。由于日期列表中的元素为 Python 的 date 对象,因此可以通过其 yearmonth 属性分别获取年和月的信息,{{ date.year }} 年 {{ date.month }} 月 反应了这个事实。

分类部分也一样:

分类

{% get_categories as category_list %}

(13) 显示的是该分类下的文章数目,这个特性会在接下来的教程中讲解如何实现,目前暂时用占位数据代替吧。

现在运行开发服务器,可以看到侧边栏显示的数据已经不再是之前的占位数据,而是我们保存在数据库中的数据了。

注意:如果你按照教程的步骤做完后发现报错,请按以下顺序检查。

检查目录结构是否正确。确保 templatetags 位于 blog 目录下,且目录名必须为 templatetags。具体请对照上文给出的目录结构。

确保 templatetags 目录下有 __init__.py 文件。

确保使用的 Django 版本不小于 1.9。

确保通过 register = template.Library()@register.simple_tag 装饰器将函数装饰为一个模板标签。

确保在使用模板标签以前导入了 blog_tags,即 {% load blog_tags %}。注意要在使用任何 blog_tags 下的模板标签以前导入它。

确保模板标签的语法使用正确,即 {% load blog_tags %},注意 { 和 % 以及 % 和 } 之间没有任何空格。

总结

本章节的代码位于:Step10: side bar。

如果遇到问题,请通过下面的方式寻求帮助。

在 页面侧边栏:使用自定义模板标签 - 追梦人物的博客 的评论区留言。

将问题的详细描述通过邮件发送到 djangostudyteam@163.com,一般会在 24 小时内回复。

更多Django 教程,请访问 追梦人物的博客。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/44395.html

相关文章

  • Django 博客开发教程 11 - 分类与归档

    摘要:侧边栏已经正确地显示了最新文章列表归档分类等信息。重启一下开发服务器,再次测试,发现可以显示归档下的文章列表了。在分类与归档追梦人物的博客的评论区留言。将问题的详细描述通过邮件发送到,一般会在小时内回复。 侧边栏已经正确地显示了最新文章列表、归档、分类等信息。现在来完善归档和分类功能,当用户点击归档下的某个日期或者分类下的某个分类时,跳转到文章列表页面,显示该日期或者分类下的全部文章。...

    happyhuangjinjin 评论0 收藏0
  • Django搭建个人博客:回到顶部浮动按钮、矢量图标、页脚沉底和粘性侧边

    摘要:本章集中介绍四个重要的小功能回到顶部浮动按钮矢量图标页脚沉底和粘性侧边栏。因为我们想在全站都拥有这个按钮,所以将刚写好的模块引用到中在后面引入注意模块用到了,因此要在后面引入。 本章集中介绍四个重要的小功能:回到顶部浮动按钮、矢量图标、页脚沉底和粘性侧边栏。 这几个功能与Django基本没啥关系,更多的是前端知识,但是对博客网站都很重要,问的读者也比较多,因此也集中讲一下好了。 回到顶...

    lovXin 评论0 收藏0
  • Django 博客开发教程 8 - 博客文章详情页

    摘要:对文章详情视图而言,每篇文章对应着不同的。在博客文章详情页追梦人物的博客的评论区留言。将问题的详细描述通过邮件发送到,一般会在小时内回复。更多教程,请访问追梦人物的博客。 首页展示的是所有文章的列表,当用户看到感兴趣的文章时,他点击文章的标题或者继续阅读的按钮,应该跳转到文章的详情页面来阅读文章的详细内容。现在让我们来开发博客的详情页面,有了前面的基础,开发流程都是一样的了:首先配置 ...

    pkwenda 评论0 收藏0
  • hexo高阶教程:next主题优化之加入网易云音乐、网易云跟帖、炫酷动态背景、定义样式,打造属于你

    摘要:我选择的是万网,阿里下面的。然后在主题配置文件下添加主题配置文件中添加自定义样式不得不说还是很人性化的,你可以个性化定制你的网站,你所有的改动需要放在主题文件的文件中,会 前言 本篇文章是在已经搭建好gitpage+hexo的博客的前提下(不懂怎么搭建的可以参考我的另一篇博文:了解githubPages+hexo搭建博客的原理 或者利用Gitpage+hexo开发自己的博客,这两篇博文...

    weizx 评论0 收藏0
  • hexo高阶教程:next主题优化之加入网易云音乐、网易云跟帖、炫酷动态背景、定义样式,打造属于你

    摘要:我选择的是万网,阿里下面的。然后在主题配置文件下添加主题配置文件中添加自定义样式不得不说还是很人性化的,你可以个性化定制你的网站,你所有的改动需要放在主题文件的文件中,会 前言 本篇文章是在已经搭建好gitpage+hexo的博客的前提下(不懂怎么搭建的可以参考我的另一篇博文:了解githubPages+hexo搭建博客的原理 或者利用Gitpage+hexo开发自己的博客,这两篇博文...

    SoapEye 评论0 收藏0

发表评论

0条评论

summerpxy

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<