Django自定义模版标签

Django提供了以下函数,可以轻松地创建自己的模板标签:

  • simple_tag:处理数据并返回字符串
  • inclusion_tag:处理数据并返回呈现的模板

模板标签必须存在于Django应用程序中。

在博客应用程序目录中,创建一个新目录,将其命名为templatetags,并向其中添加一个空的__init__.py文件。在同一文件夹中创建另一个文件,并将其命名为blog_tags.py。命名文件的方式很重要。您将使用此模块的名称来加载模板中的标记。

首先创建一个简单的标记来检索博客中发布的文章总数。

编辑刚刚创建的blog_tags.py文件

python 复制代码
from django import template
from ..models import Post


register = template.Library()

@register.simple_tag
def total_posts():
    return Post.published.count()
  • total_posts()是一个简单的模板标记,它返回到目前为止发布的文章的数量。
  • 使用@register.simple_tag 装饰器将函数注册为简单标记。
  • Django将使用函数名作为标签名。
  • 如果希望使用不同的名称注册它,可以通过指定name属性来实现,比如@register.simple_tag(name='my_tag')。

📌添加新的模板标记模块后,您将需要重新启动Django开发服务器,以便在模板中使用新的标签和过滤器。

在使用自定义模板标签之前,必须使用{% load %}标签使它们在模板中可用。

打开blog/templates/base.html模板,在顶部添加{% load blog_tags %}来加载你的模板标签模块。然后,使用创建的标记来显示您的帖子总数。只需将{% total_posts %}添加到模板中。

html 复制代码
{% load blog_tags %}
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}{% endblock %}</title>
    <link href="{% static 'css/blog.css' %}" rel="stylesheet">
</head>
<body>
    <div id="content">
        {% block content %}
        {% endblock %}
    </div>
    <div id="sidebar">
        <h2>My blog</h2>
            <p>This is my blog.I've written {% total_posts %} posts so far.</p>
    </div>
</body>
</html>

现在创建另一个标记,在博客的侧边栏中显示最新的文章。

使用包含(模版)标记。使用包含标记,可以用模板标记返回的上下文变量呈现模板。
编辑blog_tags.py文件并添加以下代码:

python 复制代码
@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}

使用blog/post/latest_posts.html指定必须用返回值呈现的模板。

模板标记将接受一个可选的count参数,默认值为5。该参数允许指定要显示的帖子数量。

📌该函数返回一个变量字典,而不是一个简单的值。包含标签必须返回一个值的字典。

现在,在templates/blog/post/下创建一个新的模板文件,并将其命名为latest_posts.html。

python 复制代码
<ul>
    {% for post in latest_posts %}
    <li>
        <a href="{{ post.get_absolute_url }}">{{ post.title}}</a>
    </li>
    {% endfor %}
</ul>

使用模板标记返回的latest_posts变量显示了一个无序的帖子列表。

编辑blog/base.html模板

html 复制代码
    <div id="sidebar">
        <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>

并添加新的模板标记以显示最后三篇文章。

最后,创建一个标签来显示评论最多的帖子,它将结果存储在一个可以重用的变量中,而不是直接输出结果。

编辑blog_tags.py文件

python 复制代码
from django import template
from ..models import Post
from django.db.models import Count

register = template.Library()

@register.simple_tag
def total_posts():
    return Post.published.count()

@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.simple_tag
def get_most_commented_posts(count=5):
    return Post.published.annotate(
        total_comments=Count('comments')
    ).order_by('-total_comments')[:count]
  • 使用annotate()函数构建QuerySet来聚合每篇文章的评论总数。
  • 使用Count聚合函数在计算字段total_comments中存储每条评论的数量
  • 按计算字段降序排列QuerySet。我们还提供了一个可选的count变量来限制返回的对象总数。

编辑blog/base.html模板

html 复制代码
{% load blog_tags %}
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}{% endblock %}</title>
    <link href="{% static 'css/blog.css' %}" rel="stylesheet">
</head>
<body>
    <div id="content">
        {% block content %}
        {% endblock %}
    </div>
    <div id="sidebar">
        <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 %}
        <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>
    </div>
</body>
</html>
  • 使用{% get_most_commentted_posts as most_commentted_posts %}将模板标记的结果存储在一个名为most_commentted_posts的新变量中。
  • 然后,使用无序列表显示返回的帖子。

关于Django模版的更多信息模板 | Django 文档 | Django (djangoproject.com)

相关推荐
每天一个秃顶小技巧23 分钟前
02.Golang 切片(slice)源码分析(一、定义与基础操作实现)
开发语言·后端·python·golang
安特尼2 小时前
招行数字金融挑战赛数据赛道赛题一
人工智能·python·机器学习·金融·数据分析
serve the people2 小时前
解决osx-arm64平台上conda默认源没有提供 python=3.7 的官方编译版本的问题
开发语言·python·conda
多多*3 小时前
Java反射 八股版
java·开发语言·hive·python·sql·log4j·mybatis
正在走向自律3 小时前
从0到1:Python机器学习实战全攻略(8/10)
开发语言·python·机器学习
西西弗Sisyphus3 小时前
Python 处理图像并生成 JSONL 元数据文件 - 灵活text版本
开发语言·python
Taichi呀3 小时前
PyCharm 快捷键指南
ide·python·pycharm
Stara05114 小时前
基于注意力机制与iRMB模块的YOLOv11改进模型—高效轻量目标检测新范式
人工智能·python·深度学习·神经网络·目标检测·计算机视觉·yolov11
Python猫4 小时前
付费专栏·Python潮流周刊电子书合集(epub、pdf、markdown)下载
python·计算机·pdf·电子书·资料
强化学习与机器人控制仿真5 小时前
openpi 入门教程
开发语言·人工智能·python·深度学习·神经网络·机器人·自动驾驶