官方文档说明:
https://docs.djangoproject.com/en/2.1/howto/custom-template-tags/
功能需求:
1、统计文章总数
2、某用户发布的文章总数统计
3、最新发布的文章列表
4、评论最多的文章列表
5、将Markdown语法解析为HTML代码
文件配置
在APP中创建一个目录templatetags(默认,必须用这个名称),然后在里面创建两个文件__init__.py和article_tags.py。
article_tags.py
from article.models import ArticlePost # 注意引入方式
from django.db.models import Count
from django.utils.safestring import mark_safe
import markdown # pip install Markdown
from django import template
register = template.Library() # 实例对象register
# 统计文章总数 通过装饰器,表明其下面的代码是自定义的simple_tag类型的标签
@register.simple_tag # simple_tag 返回的是字符串
def total_articles():
return ArticlePost.objects.count()
# 统计某个作者发布的文章总数
@register.simple_tag
def author_total_articles(user):
return user.article.count()
# 汇总最新发布的文章 inclusion_tag 返回一个模板
@register.inclusion_tag('article/list/latest_articles.html') # 参数为要渲染的模板文件
def latest_articles(n=5):
latest_articles = ArticlePost.objects.order_by('-created')[:n] # 文章对象列表集合
return {'latest_articles':latest_articles} # 返回字典类型,数据会被应用到要渲染的模板文件中
# 评论最多的文章
@register.simple_tag
def most_commented_articles(n=3):
# annotate():给QuerySet中的每个对象添加注释
# Count('comment') 得到的是ArticlePost对象关联的Comment对象的个数
return ArticlePost.objects.annotate(total_comments=Count('comments')).order_by('-total_comments')[:n]
# 自定义模板选择器,将Markdown语法解析为HTML代码
@register.filter(name='markdown') # 重命名选择器函数,将markdown_filter改为markdown
def markdown_filter(text): # 要避免函数名与第三方库的名字冲突
return mark_safe(markdown.markdown(text)) # 返回safe string
在模板文件中应用,article_titles.html
{% load article_tags %} # 引入自定义标签的声明
<p>这里已经有{% total_articles %}篇文章供你阅读</p>
author_articles.html
{% load article_tags %}
<p>{{ user.username }}</p>
<p>共发表文章{% author_total_articles user %}篇</p> # 注意参数
latest_articles.html
<ul>
{% for article in latest_articles %}
<li>
<a href="{{ article.get_url_path }}">{{ article.title }}</a>
</li>
{% endfor %}
</ul>
在article_detail.html使用{% latest_articles %} 和{% most_commented_articles %} 标签
{% load article_tags %}
<p class="text-center"><h3>最新文章</h3></p>
{% latest_articles 4 %}
<p class="text-center"><h3>最多评论文章</h3></p>
{% most_commented_articles as most_comments %} #把自定义标签所得到的对象赋值给一个变量,此步是必须的!!!!!
<ul>
{% for comment_article in most_comments %}
<li>
<a href="{{comment_article.get_url_path}}">{{ comment_article.title }}</a>
</li>
{% endfor %}
</ul>
自定义选择器
实现将Markdown语法解析为HTML代码的markdown_filter()方法中:
django.utils.safestring的作用就是将字符串编程为“safe strings”,即实实在在的字符,mark_safe()方法返回的就是这种“safe strings”。
article_detail.html
{% load article_tags %}
{{ article.body | markdown }}
网友评论