Django学习记录(十九):Django by example -- Blog(十五)
PyxYuYu opened this issue · 0 comments
PyxYuYu commented
I always like walking in the rain, so no one can see me crying.
0x01 Django
- Build a Blog Application
Creating custom template tags
- 创建自定义的模板标签
Django
提供了很多内建的模板标签,比如{% if %}
{% block %}
等,然而Django
也允许我们创建自定义的模板标签来执行行为Django
提供了以下几个函数来创建:simple_tag
接受数据返回一个字符串inclusion_tag
通过渲染其他模板显示数据assignment_tag
接受数据并且在context
中设置
- 模板标签必须存在于
Django app
中,也就是模板标签必须绑定app
,该app
应该包含一个templatetags
目录,该目录存在于blog app
下,和models.py
views.py
同一层级,在其中新建一个__init__.py
空文件,这样Django
可认为是一个Python
包 - 在该目录下,新建一个
Python
模块文件:blog_tags.py
结构如下
blog/ __init__.py models.py ... templatetags/ __init__.py blog_tags.py
- 在模板文件中就可以导入
blog_tags.py
来使用自定义标签
{% load blog_tags %}
- 接下来创建一个简单的标签用于检索所有公开的
posts
,编辑blog_tags.py
from django import template register = template.Library() from ..models import Post @register.simple_tag def total_posts(): return Post.published.count()
- 每个模板标签模块都需要包含一个名为
register
的变量(一个有效的标签库),这个变量是template.Library
的实例,用于注册模板标签和过滤器 - 上面定义了一个标签
total_posts
: 用@register.simple_tag
定义下面的函数为一个简单标签并且注册了它,Django
会用函数名作为标签名,如果要用其他名称可以用
@register.simple_tag(name='my_tag')
- 将自定义标签运用到模板中,先用
{% load %}
导入,{% total_posts %}
就是我们的自定义标签,编辑blog/base.html
{% load blog_tags %} ... <p>This is my blog. I've written {% total_posts %} posts so far.</p> ...
- 注意:如果需要使用新的自定义标签或者过滤器的话,需要重新启动开发服务器
- 上面创建的是简单标签,接下来创建一个包含标签,这个标签用于显示最后更新的
posts
- 编辑
blog_tags.py
增加
@register.inclusion_tag('blog/post/latest_posts.html') def show_latest_posts(count=2): latest_posts = Post.published.order_by('-publish')[:count] return {'latest_posts': latest_posts}
- 这里利用
@register.inclusion_tag
注册了模板标签,指定了一个被渲染的模板和其中返回的变量,后面函数接收一个参数count
(默认为2,指定了我们希望显示的数量),函数最后返回的是一个字典 - 包含标签最后返回的都是一个字典,通常被用作渲染指定的模板,这个模板标签可以传送一个自定义的
count
,比如{% show_latest_posts 4 %}
- 在
blog/post/
下创建一个latest_posts.html
模板
<ul> {% for post in latest_posts %} <li> <a href="{{ post.get_absolute_url }}">{{ post.title }}</a> </li> {% endfor %} </ul>
latest_posts.html
模板显示的是没有顺序的posts
列表,接下来编辑blog/base.html
模板,添加自定义的标签显示最近更新的3个posts
<p>This is my blog. I've written {% total_posts %} posts so far.</p> <h3>Latest posts</h3> {% show_latest_posts 3 %}
- 接着创建一个
assignment_tag
,和simple_tag
类似,最大的区别就是它可以存储标签结果为一个变量去代替直接输出,这样方便前台模板页面对内容的再次处理和展现,如{% assignment_tag as variable %}
- 创建
assignment_tag
用于显示评论最多的posts
,编辑blog_tags.py
,添加
from django.db.models import Count @regiest assignment_tag def get_most_commented_posts(count=2): return Post.published.annotate(total_comments=Count('comments')).order_by('-total_comments')[:count]
- 利用聚合函数,通过统计
posts
数量来获得评论的数量total_comments
- 编辑
blog/base.html
模板,添加在show_latest_posts
后
<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>
- 注意:简单标签返回的是一个字符串,而
assignment_tag
重新定义后可以如上所示成为一个列表