自定义标签威力强大之处在于不通过视图就可以处理数据和添加到模板中。
现在再来创建一个用于在侧边栏显示最新发布的文章的自定义标签。这次通过inclusion_tag渲染一段HTML代码。编辑blog_tags.py文件,添加如下内容:
@register.inclusion_tag(\'blog/post/latest_posts.html\') def show_latest_posts(count=5): latest_posts = Post.published.order_by(\'-publish\')[:count] return {\'latest_posts\': latest_posts}在上边的代码里,使用@register.inclusion_tag装饰器装饰了自定义函数show_latest_posts,同时指定了要渲染的模板为blog/post/latest_posts.html。我们的模板标签还接受一个参数count,通过Post.published.order_by(\'-publish\')[:count]切片得到指定数量的最新发布的文章。注意这个自定义函数返回的是一个字典对象而不是一个具体的值。inclusion_tag必须返回一个类似给模板传入变量的字典,用于在blog/post/latest_posts.html中取得数据并渲染模板。刚刚创建的这一切在模板中以类似{% show_latest_posts 3 %}的形式来使用。
那么在模板里如何使用呢,这是一个带参数的tag,就像之前使用内置的那样,在标签后边加参数: {% show_latest_posts 3 %}
在blog/post/目录下创建latest_posts.html文件,添加下列代码:
<ul> {% for post in latest_posts %} <li> <a href="{{ post.get_absolute_url }}">{{ post.title }}</a> </li> {% endfor %} </ul>在上边的代码里,使用lastest_posts显示出了一个未排序的最新文章列表。然后编辑blog/base.html,加入新标签以显示最新的三篇文章:
<div> <h2>My blog</h2> <p>This is my blog. I\'ve written {% total_posts %} posts so far.</p> <h3>Latest posts</h3> {% show_latest_posts 3 %} </div>模板中调用了自定义标签,然后传入了一个参数3,之后这个标签的位置会被替换成被渲染的模板。
现在返回浏览器,刷新页面,可以看到侧边栏显示如下:
最后再来创建一个simple_tag,将数据存放在这个标签内,而不是像我们创建的第一个标签一样直接展示出来。我们使用这种方法来显示评论最多的文章。编辑blog_tags.py,添加下列代码:
from django.db.models import Count @register.simple_tag def get_most_commented_posts(count=5): return Post.published.annotate(total_comments=Count(\'comments\')).order_by(\'-total_comments\')[:count]在上边的代码里,使用annotate,对每篇文章的评论进行计数然后按照total_comments字段降序排列,之后使用[:count]切片得到评论数量最多的特定篇文章,
除了Count之外,Django提供了其他聚合函数Avg,Max,Min和Sum,聚合函数的详情可以查看https://docs.djangoproject.com/en/2.0/topics/db/aggregation/。
编辑blog/base.html把以下代码追加到侧边栏<div>元素内部:
<h3>Most commented posts</h3> {% get_most_commented_posts as most_commented_posts %} <ul> {% for post in most_commented_posts %} <li> <a href="{{ post.get_absolute_url }}">{{ post.title }}</a> </li> {% endfor %} </ul>在这里使用了as将我们的模板标签保存在一个叫做most_commented_posts变量中,然后展示其中的内容。
现在打开浏览器刷新页面,可以看到新的页面如下:
关于自定义模板标签的详情可以查看https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/。
1.2自定义模板过滤器Djangon内置很多模板过滤器用于在模板内修改变量。模板过滤器实际上是Ptyhon函数,接受1或2个参数-其中第一个参数是变量,第二个参数是一个可选的变量,然后返回一个可供其他模板过滤器操作的值。一个模板过滤器类似这样:{{ variable|my_filter }},带参数的模板过滤器类似:{{ variable|my_filter:"foo" }},可以连用过滤器,例如:{{ variable|filter1|filter2 }}。