Django框架之模板层

发布于:2024-05-04 ⋅ 阅读:(33) ⋅ 点赞:(0)

一、模版语法

1、模版初识

(1)语法

  • {{ }}: 变量相关

  • {% %}: 逻辑相关

(2)变量

① 传值
  • 在Django的模板语言中按此语法使用:
    • {{ 变量名 }}。
  • 当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。
  • 变量的命名包括任何字母数字以及下划线 (“_”)的组合。
  • 变量名称中不能有空格或标点符号。
② 取值
  • 点(.)在模板语言中有特殊的含义。
    • 当模版系统遇到点(“.”),它将以这样的顺序查询:
      • 字典查询(Dictionary lookup)
      • 属性或方法查询(Attribute or method lookup)
      • 数字索引查询(Numeric index lookup)
③ 注意事项
  • 如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。
  • 如果使用的变量不存在, 模版系统将插入 string_if_invalid 选项的值, 它被默认设置为’’ (空字符串) 。

2、模板语法的传值

(1)路由

# 模板语法传值
from django.urls import path
from app02 import views
urlpatterns = [
    path("index/",views.index)
]

(2)基本数据类型传值

views.py

def index(request):
    # 模版语法可以传递的后端python数据类型
    # 整型
    n = 123
    # 浮点型
    f = 11.11
    # 字符串
    s = '权浩大傻逼'
    # 布尔
    b = True
    # 列表
    l = ['xiao', 'quan', 'zheng']
    # 字典
    d = {'username': 'xiao', 'age': 18, 'info': '这个人真帅'}
    # 集合
    se = {'乐乐', '牛牛', '图图'}
	# 元组
    tu = (11, 22, 33)
    return render(request, 'index.html', locals())

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<p>{{ n }}</p>
<p>{{ f }}</p>
<p>{{ s }}</p>
<p>{{ b }}</p>
<p>{{ l }}</p>
<p>{{ d }}</p>
<p>{{ se }}</p>
<p>{{ tu }}</p>
</body>
</html>

页面展示结果:

123

11.11

权浩大傻逼

True

['xiao', 'quan', 'zheng', 'niu', 'pa']

{'username': 'xiao', 'age': 18, 'info': '这个人真帅', 'hobby': [111, 222, 333, {'info': '666'}]}

{'乐乐', '牛牛', '图图'}

(11, 22, 33)

(3)函数传值

  • 传递函数名会自动加括号调用

  • 但是模版语法不支持给函数传额外的参数

    • 如果有参数,不会报错也不会执行该函数

views.py

 def func():
        print(9899)
        return '下一位'

index.html

<p> {{ func }} </p>

页面展示结果:

后端控制台打印  9899
浏览器页面展示  下一位

(4)类与对象传值

  • 传类名的时候也会自动加括号调用(实例化)

  • 内部能够自动判断出当前的变量名是否可以加括号调用,如果可以就会执行,针对的是函数名和类名

views.py

class MyClass(object):
    # 普通方法
    def get_self(self):
        return 'self'
   
	# 静态方法
    @staticmethod
    def get_func(self):
        return 'func'
                 
	# 绑定给类的静态方法
    @classmethod
    def get_class(self):
        return 'cls'

    # 对象被展示到html页面上,就类似于执行了打印操作也会触发__str__方法
    def __str__(self):
        return '来两位'
obj = MyClass()

index.html

<p>{{ MyClass }}</p>
<p>{{ obj }}</p>
<p>{{ obj.get_self }}</p>
<p>{{ obj.get_func }}</p>
<p>{{ obj.get_class }}</p>

页面展示结果:

来两位
来两位
self

cls

3、模版语法的取值

(1)路由

# 模板语法传值
from django.urls import path
from app02 import views
urlpatterns = [
    path("index/",views.index)
]

(2)具体应用

  • Django模版语法的取值是固定的格式,只能采用"."

  • 既可以点键,也可以点索引,还可以混着用

views.py

def index(request):
    # 模版语法可以传递的后端python数据类型
    # 整型
    n = 123
    # 浮点型
    f = 11.11
    # 字符串
    s = '权浩大傻逼'
    # 布尔
    b = True
    # 列表
    l = ['xiao', 'quan', 'zheng']
    # 字典
    d = {'username': 'xiao', 'age': 18, 'info': '这个人真帅'}
    # 集合
    se = {'乐乐', '牛牛', '图图'}
	# 元组
    tu = (11, 22, 33)
    return render(request, 'index.html', locals())

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<p>{{ d.username }}</p>
<p>{{ l.1 }}</p>
<p>{{ d.hobby.3.info }}</p>
</body>
</html>

页面展示结果:

xiao
quan
666

二、过滤器

1、过滤器的语法

过滤器就类似于一些模版语法内置的内置方法

{{ value|filter_name:参数 }}
  • 使用管道符"|"来应用过滤器。
  • 例如:
    • {{ name|lower }}会将name变量应用lower过滤器之后再显示它的值。
    • lower在这里的作用是将文本全都变成小写。

2、过滤器的使用

(1)default

如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:

{{ value|default: "nothing"` }}

(2)length

返回值的长度。它对字符串和列表都起作用。例如:

{{ value|length }}

如果 value 是 [‘a’, ‘b’, ‘c’, ‘d’],那么输出是 4。

(3)filesizeformat

将值格式化为一个 “人类可读的” 文件尺寸 (例如‘13 KB’,‘4.1 MB’,‘102 bytes’, 等等)。例如:

{{ value|filesizeformat }}

如果 value 是 123456789,输出将会是 117.7 MB

(4)date

如果 value=datetime.datetime.now(),将返回当前时间的年-月-日 时:分:秒格式。

{{ value|date: "Y-m-d H:m:s" }}  

(5)slice

如果 value=“hello world”,则结果为ello worl (也是顾头不顾尾)

{{ value|slice: "2:-1" }}

(6)truncatechars

如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“…”)结尾。(truncatewords则是按单词数目截断(单词与单词间按空格算),用法相同)

**参数:**要截断的字符数

例如:

{{ value|truncatechars: 3 }}

如果 value 是 Joel,输出将为“Joe…”。

(7)lower 和 upper

将字符串转换为小写或大写。

{{ my_string | lower }}
{{ my_string | upper }}

(8)add

将变量与另一个值相加。

{{ my_number | add:5 }}

如果后面add后面不是数字,则执行拼接操作

{{ str | add:msg }}

(9)join

拼接操作,以逗号拼接

{{ my_list | join:", " }}

(10)cut

移除特定的字符,移除空格符

{{ msg|cut:' ' }}

3、转义使用详细介绍

Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。

但是有的时候我们可能不希望这些HTML元素被转义

比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。

以后在写全栈项目时,前端代码不一定必须在前端页面书写,也可以选择先在后端写好,再传递给前端页面展示

(1)前端转义(safe)

msg = '<h1>斋藤</h1>'
<p>转义字符(不转义) {{ msg }}</p>

<p>转义字符(转义) {{ msg|safe }}</p>
转义字符(不转义) <h1>斋藤</h1>

转义字符(转义)

斋藤(已变成h1标题格式)

(2)后端转义(mark_safe)

from django.utils.safestring import mark_safe
res = mark_safe('<h1>飞鸟</h1>')
<p>转义字符(转义) {{ res }}</p>
转义字符(转义)

飞鸟(已变成h1标题格式)

三、标签

1、for循环

(1)普通for循环

<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% endfor %}
</ul>

(2)for循环可用的一些参数

Variable Description
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环

(3)for … empty

在Django模板中,for...empty结构用于在循环中处理空列表或查询集的情况。当一个循环没有任何数据时,for...empty结构允许您在这种情况下执行一些特定的操作或显示一些特定的内容。

下面是一个简单的示例,演示了如何在Django模板中使用for...empty结构:

<ul>
    {% for item in my_list %}
        <li>{{ item }}</li>
    {% empty %}
        <li>No items found.</li>
    {% endfor %}
</ul>

在这个示例中,如果my_list为空,那么模板将显示No items found.。否则,它会遍历my_list中的每个元素并将其显示为列表项。

for...empty结构的语法如下:

  • {% for item in my_list %}:开始一个循环,遍历my_list中的每个元素。
  • {% empty %}:指定在循环中没有任何数据时要执行的内容。
  • {% endfor %}:结束循环块。

使用for...empty结构可以使模板更具弹性,能够处理不同情况下的数据展示需求。通过合理利用for...empty,您可以更好地控制模板中数据的呈现方式,使其更具交互性和用户友好性。

2、if 判断

(1)if ~ elif ~ else

在Django模板中,您可以使用ifelifelse语句来根据条件显示不同的内容。这些语句允许您根据变量的值或其他条件来控制模板中的显示逻辑。

{% if user.is_authenticated %}
    <p>Welcome, {{ user.username }}!</p>
{% elif user.is_staff %}
    <p>Hello, staff member!</p>
{% else %}
    <p>Please log in to access this content.</p>
{% endif %}

在这个示例中,根据user的身份和认证状态,模板会显示不同的消息。如果用户已经认证,则会显示欢迎消息;如果用户是员工,则显示员工相关消息;否则显示登录提示。

语法解释如下:

  • {% if user.is_authenticated %}:检查用户是否已认证。
  • {% elif user.is_staff %}:如果用户未认证但是员工,则执行此部分。
  • {% else %}:如果以上条件都不满足,则执行此部分。
  • {% endif %}:结束条件块。

使用ifelifelse语句可以根据不同的条件动态地呈现内容,增强模板的交互性和个性化。这使得您能够根据用户的身份、权限或其他条件来定制页面内容,提供更好的用户体验。

(2)只有 if 和 else

如果您只需要在 Django 模板中使用 ifelse,而不需要 elif,那么也是完全可行的。下面是一个简单示例,演示了如何在 Django 模板中只使用 ifelse

{% if user.age >= 18 %}
    <p>Welcome, {{ user.username }}!</p>
{% else %}
    <p>Please log in to access this content.</p>
{% endif %}

在这个示例中,如果用户年龄已经成年,则显示欢迎消息,否则显示登录提示。

语法解释如下:

  • {% if user.age >= 18 %}:检查用户是否已成年。
  • {% else %}:如果用户未承诺,则执行此部分。
  • {% endif %}:结束条件块。

使用 ifelse 语句可以根据简单的条件来控制模板中的内容显示,适用于许多基本的情况。如果您只需要简单地根据一个条件来决定显示什么内容,那么使用 ifelse 就足够了。

if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。

3、with

在 Django 模板中,with 标签用于创建一个新的变量并将其赋值给指定的值。这在模板中有时很有用,可以帮助您更清晰地组织和管理模板中的数据。

  • 定义一个中间变量,多用于给一个复杂的变量起别名。
  • 注意等号左右不要加空格。
{% with total_items=user.cart.items.count %}
    <p>Your cart contains {{ total_items }} item(s).</p>
{% endwith %}

或者

{% with user.cart.items.count as total_items %}
    <p>Your cart contains {{ total_items }} item(s).</p>
{% endwith %}

在这个示例中,with 标签用于计算用户购物车中物品的总数,并将结果存储在 total_items 变量中。然后,您可以在 with 块内部使用这个新变量来显示购物车中物品的总数。

语法解释如下:

  • {% with total_items=user.cart.items.count %}:创建一个名为 total_items 的变量,并将用户购物车中物品的数量赋值给它。
  • {{ total_items }}:在 with 块内部使用 total_items 变量来显示购物车中物品的总数。
  • {% endwith %}:结束 with 块。

with 标签在模板中很有用,可以帮助您避免重复计算相同的值,并提高模板的可读性和维护性。您可以根据需要在模板中使用 with 标签来创建和管理变量。

4、csrf_token

在Django中,csrf_token标签用于在表单中包含跨站请求伪造(CSRF)令牌。CSRF令牌是一种安全机制,用于防止恶意网站利用已认证用户的身份在用户不知情的情况下执行未经授权的操作。

<form method="post">
    {% csrf_token %}
    <!-- 其他表单字段 -->
    <button type="submit">提交</button>
</form>

在这个示例中,{% csrf_token %}标签会在表单中插入CSRF令牌。当用户提交表单时,Django会验证这个CSRF令牌,以确保请求是合法的。

请确保在包含表单的每个POST请求中使用{% csrf_token %}标签,以保护您的应用免受CSRF攻击。

如果您在Django视图中处理POST请求,并且遇到CSRF验证失败的问题,可能是因为未在表单中包含CSRF令牌。在这种情况下,请确保在表单中正确地包含{% csrf_token %}标签。

5、注释

{# ... #}

6、注意事项

(1)Django的模板语言不支持连续判断

即不支持以下写法:

{% if a > b > c %}
...
{% endif %}

(2)Django的模板语言中属性的优先级大于方法

def xx(request):
    d = {"a": 1, "b": 2, "c": 3, "items": "100"}
    return render(request, "xx.html", {"data": d})
  • 如上,我们在使用render方法渲染一个页面的时候
    • 传的字典d有一个key是items并且还有默认的 d.items() 方法
    • 此时在模板语言中:
{{ data.items }}
  • 默认会取d的items key的值。

7、forloop介绍

在Django模板中,您可以使用for标签来循环遍历列表或查询集中的元素。forloop变量是一个用于追踪循环状态的特殊变量,它提供了有关当前循环的信息,如当前循环的索引、计数等。

<ul>
    {% for item in items %}
        <li>
            {{ forloop.counter }}. {{ item }}
        </li>
    {% endfor %}
</ul>

在这个示例中,假设items是一个包含元素的列表。在for循环中,我们遍历items列表,并对每个元素执行操作。forloop.counter表示当前循环的计数(从1开始),因此我们在每个列表项前显示了计数。

您还可以使用其他forloop变量,例如forloop.counter0(从0开始的计数)、forloop.first(布尔值,表示是否是循环中的第一个元素)和forloop.last(布尔值,表示是否是循环中的最后一个元素)等。

这个示例将会生成一个带有编号列表项的无序列表,每个列表项包含一个元素和对应的编号。这是一个简单但常见的用法,可以帮助您更好地理解如何在Django模板中使用forloop变量。

8、混用 forloop + if 示例

d = ["你好", "我好", "大家好"]
{% for foo in lll %}
    {% if forloop.first %}
        <p>这是我的第一次</p>
    {% elif forloop.last %}
        <p>这是最后的一次啊</p>
    {% else %}
        <p>{{ foo }}</p>
    {% endif %}
    {% empty %}
        <p>for循环的可迭代对象内部没有元素 根本没法循环</p>
{% endfor %}

9、处理字典的其他办法

 d = {'username': 'xiao', 'age': 18, 'info': '这个人真帅', 'hobby': [111, 222, 333, {'info': '666'}]}
{% for foo in d.keys %}
    <p>{{ foo }}</p>
{% endfor %}
{% for foo in d.values%}
    <p>{{ foo }}</p>
{% endfor %}
{% for foo in d.items %}
    <p>{{ foo }}</p>
{% endfor %}

四、自定义过滤器、标签以及inclusion_tag

0、前提

先三步走

  • 要在应用下创建一个名字必须是templatetags文件夹
  • 在该文件夹内创建 任意 名称的py文件
  • 在该文件内必须写下面的话
from django import template

register = template.Library()

1、自定义过滤器

  • 过滤器只能最多两个参数

(1)templatetags/mytag.py

from django import template

register = template.Library()


# 自定义过滤器
@register.filter(name='xiao')
def my_sum(v1, v2):
    return v1 + v2

(2)页面使用

{% load mytag %}
<p>{{ n|xiao:111 }}</p>

2、自定义标签

  • 自定义标签参数可以有多个

(1)templatetags/mytag.py

from django import template

register = template.Library()


# 自定义标签
@register.simple_tag(name='quan')
def index(a, b, c, d):
    return '%s-%s-%s-%s' % (a, b, c, d)

(2)页面使用

  • 标签多个参数彼此之间空格隔开
{% load mytag %}
<p>{% quan 'dsb' 111 222 333 %}</p>

3、自定义inclusion_tag

  • 先定义一个方法,在页面上调用该方法,并且可以传值
  • 该方法会生成一些数据然后传递给一个前端页面
  • 再将渲染好的页面返回给前端

(1)templatetags/mytag.py

from django import template

register = template.Library()


# 自定义inclusion_tag
@register.inclusion_tag('03 left_menu.html')
def left(n):
    data = ['第{}项'.format(i) for i in range(n)]
    # 第一种 将data传值给html页面的方式(推荐使用)
    return locals()  # 将data传递给left_menu.html
    # 第二种
    # return {'data':data}

(2)left_menu.html

<ul>
    {% for foo in data %}
    	<li>{{ foo }}</li>
    {% endfor %}

</ul>

(3)index.html

<h1>自定义标签的使用</h1>
{% load mytag %}

{% left 5 %}

(4)页面展示

  • 第0项
  • 第1项
  • 第2项
  • 第3项
  • 第4项

(5)总结

当html页面的某一个地方的页面需要传参数才能动态的渲染出来,并且在多个页面上都需要使用到的局部,那么就考虑将该局部页面做成 inclusion_tag 形式

五、模版的继承

  • 某些页面的整体大差不差,但是某一些局部在做变化

1、模板

layouts.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Title</title>
  {% block page-css %}
  
  {% endblock %}
</head>
<body>

<h1>这是母板的标题</h1>

{% block page-main %}

{% endblock %}
<h1>母板底部内容</h1>
{% block page-js %}

{% endblock %}
</body>
</html>
  • 注意:我们通常会在母板中定义页面专用的CSS块和JS块,方便子页面替换。

2、继承母板

  • 在子页面中在页面最上方使用下面的语法来继承母板。
{% extends 'layouts.html' %}

3、块(block)

  • 通过在母板中使用{% block xxx %}来定义"块"。
  • 在子页面中通过定义母板中的block名来对应替换母板中相应的内容。
{% block page-main %}
  <p>世情薄</p>
  <p>人情恶</p>
  <p>雨送黄昏花易落</p>
{% endblock %}

六、模板的导入

{% include %} 标签是Django模板系统中的一个指令,用于在模板中包含其他模板文件的内容。这个标签的语法如下:

{% include "template_name" %}

其中,"template_name" 是要包含的模板文件的路径。您可以指定相对路径或绝对路径来引用其他模板文件。通常,被包含的模板文件包含一些可重复使用的代码块,比如导航栏、页脚、侧边栏等。

使用{% include %}标签的好处包括:

  1. 代码重用:可以将通用的代码块放在单独的模板文件中,然后在需要的地方使用{% include %}来引入,避免重复编写相同的代码。
  2. 模块化:通过将页面分解为多个可重用的模块,可以更好地组织和管理模板代码。
  3. 维护性:当需要对共享的代码进行更改时,只需修改被包含的模板文件,所有引用该文件的地方都会自动更新。
  4. 灵活性:可以在需要的地方动态地包含不同的模板文件,根据需求定制页面的外观和功能。

总之,{% include %}标签是Django模板系统中一个强大的工具,将页面的某一个局部当成模块的形式,哪个地方需要就可以直接导入使用即可

七、静态文件加载

1、{% static %}

settings.py

# 静态文件配置
STATICFILES_DIRS = [  
    os.path.join(BASE_DIR, 'static')
]
  • 加载Django的静态文件
{% load static %}
<img src="{% static "images/hi.jpg" %}" alt="Hi!" />
  • 引用JS文件时使用:
{% load static %}
<script src="{% static "mytest.js" %}"></script>
  • 某个文件多处被用到可以存为一个变量
{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>

2、{% get_static_prefix %}

  • 相当于获取到了 static 文件夹的文件夹绝对路径,从绝对路径再往下找静态文件
{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />
  • 或者
{% load static %}
{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

八、simple_tag

1、介绍

  • 许多模板标签接受多个参数——字符串或模板变量——并仅根据输入参数和一些额外信息进行某种处理,并返回结果。例如, current_time 标签可能接受一个格式字符串,并将时间按照字符串要求的格式返回。
  • 为了简化创建标签类型的流程,Django 提供了一个助手函数, simple_tag。该函数实际是 django.template.Library 的一个方法,该函数接受任意个数的参数,将其封装在一个 render 函数以及上述其它必要的位置,并用模板系统注册它。
  • 我们的 current_time 函数因此能这样写:
import datetime
from django import template

register = template.Library()

@register.simple_tag
def current_time(format_string):
    return datetime.datetime.now().strftime(format_string)

2、simple_tag 助手函数注意事项

  • 检测要求参数的个数等在调用函数时就已完成,所以我们无需再做。
  • 包裹参数(如果有的话)的引号已被删除,所以我们收到一个普通字符串。
  • 如果参数是一个模板变量,函数将传递变量值,而不是变量本身。

3、模板转义

  • 若模板上下文处于自动转义模式,不像其它标签实体, simple_tag 通过 conditional_escape() 传递输出,为了确保输出正确的 HTML,避免 XSS 漏洞的威胁。
  • 如果不需要额外转义,你可能需要在万分确定您的代码不会引入任何 XSS 漏洞的情况下使用 mark_safe()。如果只是构建小的 HTML 片段,强烈建议使用 format_html(),而不是 mark_safe()

4、访问上下文对象

  • 若您的模板标签需要访问当前上下文,你可以在注册标签时传入 takes_context 参数:
@register.simple_tag(takes_context=True)
def current_time(context, format_string):
    timezone = context['timezone']
    return your_get_current_time_method(timezone, format_string)
  • 注意,第一个参数必须是 context

  • 更多关于 takes_context 选项如何工作的信息,参见章节 包含标签

5、重命名标签

  • 若你需要重命名标签,你可以为其提供一个自定义名称:
register.simple_tag(lambda x: x - 1, name='minusone')

@register.simple_tag(name='minustwo')
def some_function(value):
    return value - 2

6、接收参数

  • simple_tag 函数可以接受任意数量的位置或关键字参数。例如:
@register.simple_tag
def my_tag(a, b, *args, **kwargs):
    warning = kwargs['warning']
    profile = kwargs['profile']
    ...
    return ...

7、在模板中使用

  • 随后在模板中,任意数量的,以空格分隔的参数会被传递给模板标签。
  • 与 Python 中类似,关键字参数的赋值使用等号(“=”),且必须在位置参数后提供。例子:
{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}
  • 将标签结果存入一个模板变量而不是直接将其输出是可能的。
  • 这能通过使用 as 参数,后跟变量名实现。这样做能让你在期望的位置输出内容:
{% current_time "%Y-%m-%d %I:%M %p" as the_time %}
<p>The time is {{ the_time }}.</p>

8、示例

(1)后端

  • 新建一个文件存储自定义标签函数
  • app01/tags/my_tags.py
import datetime
from django import template

register = template.Library()


@register.simple_tag
def current_time(format_string):
    return datetime.datetime.now().strftime(format_string)


@register.simple_tag
def my_tag(a, b, *args, **kwargs):
    print(a)
    print(b)
    print(args)
    print(kwargs)
    warning = kwargs['warning']
    profile = kwargs['profile']
    print(warning)
    print(profile)
    ...
    return "OKK"
  • 在Django中注册标签函数
  • settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates']
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
            # 新增一个配置项
            'libraries': {
                # 前端加载的标签名:标签函数所在的文件目录
                "my_tag": "app01.tags.my_tags",
            },
        },

    },
]

(2)前端

{% load my_tag %}
{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}
{% current_time "%Y-%m-%d %I:%M %p" as the_time %}
<p>The time is {{ the_time }}.</p>
OKK
The time is 2024-02-24 03:23 AM.

九、inclusion_tag示例

  • 多用于返回html代码片段
  • 示例:
  • templatetags/my_inclusion.py
from django import template

register = template.Library()


@register.inclusion_tag('result.html')
def show_results(n):
    n = 1 if n < 1 else int(n)
    data = ["第{}项".format(i) for i in range(1, n+1)]
    return {"data": data}
  • templates/snippets/result.html
<ul>
  {% for choice in data %}
    <li>{{ choice }}</li>
  {% endfor %}
</ul>
  • templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>inclusion_tag test</title>
</head>
<body>

{% load inclusion_tag_test %}

{% show_results 10 %}
</body>
</html>

网站公告

今日签到

点亮在社区的每一天
去签到