Django之模板层
目录
模板语法传值
特性:
# 1. 传值调用
* {{ xxx }} : 主要与数据值相关
1. 八大数据类型:都可以传值
2. 函数: 可以传,但不支持传参数,返回到前端内容为后台函数的返回值
3. 类名:传到前端会自动加括号,产生一个对象,返回给前端一个对象
4. 对象:传到前端就是一个对象,对象还可以使用点的方式点它定义过的方法。
5. 文件对象可以展示并调用方法
* {% xxx %} : 主要用与逻辑相关,如for/if等,加载模块,加载静态文件等。
# 2. 方法调用
* 对于需要使用()符号进行调用的方法,在前台不需要加()调用,只需要点名字.xxx即可。如:
# 后台传值为:
f=open(r'xxx', 'rb')
# 前台调用:
{{ f }}
# 前台调用read方法
{{ f.read }} # 最后不需要加括号
- 方法一:有针对性的传值
def myFunc(request):
name = 'jack'
age = 18
hobby = 'draw'
# 使用键值对传值,键的名字自定义,值的名字为变量名
return render(request, 'login.html', {'my_num1': name, 'my_num2': age, 'my_num3': hobby})
- 方法二:直接传全部值
def myFunc(request):
name = 'jack'
age = 18
hobby = 'draw'
# 使用locals()直接传所有值,传到前台调用时,键就是变量名,值为变量对应的值。
return render(request, 'login.html', locals())
- 优缺点
- 方法一 优点:传值比较有针对性,需要什么传什么,有针对性,节省资源。 缺点:键值对编写繁琐,浪费时间
- 方法二 优点:传值比较方便,不需要挨个指定键值对。 缺点: 会传不必要的值到前端,浪费资源
模板语法之取值
语法{{ 数据值 }}
- 取普通数据值
{{ 数据值 }}
- 取字典或列表
# 后端定义
test = {'name': 'Rose', 'age': 18, 'hobby':['dance', 'draw', {'Ball': 'Basketball', 'Ball2': 'Football'}]}
# 前端如果要取Football这个值,使用"."的方式即可
<p>{{ test.hobby.2.Ball2 }}</p>
# Django可以自动分辨是键还是索引
模板语法注释
<!-- xxx --> # 这种前端在查看源码时可以看到此注释
{# xxxxxx #} # 这种注释,前端查看源码时看不到
模板语法之常用过滤器
- 相当于python的内置函数
语法: {{ value|filter_name:参数 }}
{{ value|default: "nothing"}} # 如果value值没传的话就显示nothing
{{ x|add:10 }} # 后台传入的变量x如果为数值则进行加法运算,如果为str,则进行拼接
{{ x|length }} # 显示字符串长度
{{ x|slice:'1:4' }} # 切片,示例中为从索引1切到索引4
{{ x|truncatechars:3 }} # 选3个字符(实际是2个,最后未被显示的以“...”结尾,也算一个字符),主要用于摘要
{{ x|truncatewords:1 }} # 按单词截取(其实是以空格截取)(截取1个单词,其余以"..."显示)
ctime = datetime.today()
{{ ctime|date:'Y-m-d' }} # 显示时间
{{ ctime|date:'Y年-m月-d日 H:i:s' }} # 显示时间,也可以自己加字符进行显示
# 文件大小
file_size=77210
{{ file_size|filesizeformat }} # 把数据使用最佳单位进行展示,后台数字指的是字节
#
h1 = <h1>我是一个后端</h1>
<p>{{ h1|safe }}</p> # 这样传到前端会自动识别成h1标题
模板层之标签语法
if语法
{% if 条件 %} # 注意,条件可以直接写后端传过来的数据
<p>xxxx</p>
{% elif 条件 %}
<p>xxxx</p>
{% else %}
<p>xxxx</p>
{% endif %}
for循环
{% for i in xxx %}
<p>{{ xxx }}</p>
{% forloop %} # 可以结合if判断是第一次循环、最后一次循环、第几次循环
{% empty %} # 如果传入的值不为空值,就执行empty内的内容
{% endfor %}
for循环之forloop
需要注意的是,在for循环中,有一个{% forloop %}
返回值:
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 3, 'revcounter0': 2, 'first': True, 'last': False}
几个重要字段 索引 计数 开始 结束
# 具体使用
{% for l1_obj in l1 %}
{% if forloop.first %}
<p>第一次循环</p>
{% elif forloop.last %}
<p>最后一次循环</p>
{% else %}
<p>这是中间循环</p>
{% endif %}
{% endfor %}
'''
使用场景:比如多个字段需要使用特殊符号隔开,如使用逗号
user_list = ['a', 'b', 'c', 'd']
前端:
{% for user in user_list %}
<span>{{ user|add:',' }}</span>
{% endfor %}
页面显示结果:
a, b, c, d,
注意在正常情况下,最后一个字符结束应该没有逗号,这时就可以使用forloop
{% for user in user_list %}
{% if forloop.last %}
<span>{{ user }}</span>
{% else %}
<span>{{ user|add:',' }}</span>
{% endif %}
{% endfor %}
最终返回结果为:a, b, c, d 结尾处没有标点符号
'''
for循环之empty
{% empty %} # 如果传入的值为空值,如空字符串、空字典、空列表,就执行empty内的内容
with别名(较少使用)
- 当后端定义的字典或列表较为复杂时,用点的方式过于繁琐,还需要多次调用的情景下,就可以使用别名。
# 后端定义
test = {'name': 'Rose', 'age': 18, 'hobby':['dance', 'draw', {'Ball': 'Basketball', 'Ball2': 'Football'}]}
# 前端如果要取Football这个值,使用"."的方式
<p>{{ test.hobby.2.Ball2 }}</p>
# 太过复杂
{% with test.hobby.2.Ball2 as f %}
<p>{{ f }}</p> # 后续再需要这个值,只需要使用别名即可
{% endwith %}
自定义过虑器、标签及inclusion_tag(了解)
- 当Django提供使用的过虑器、标签等无法满足使用时,还可以自定义使用
# 分为三步
# 1. 在应用下创建一个名字templatetags(必须)目录
# 2. 在templatetags目录下创建任意名称的py文件
# 3. 在创建的py文件中添加如下两行代码
# 4. 前端使用{% load py文件 %}导入
自定义过虑器
- 只能定义两个参数,使用{{ xx|xxx 参数 }}调用
# 例如创建一个mytags.py文件,内容如下
from django import template
register = template.Library() # 变量名必须为register
# 之后就可以自定义了
- 过虑器最多只能接收两个参数,示例:
# 后台
@register.filter(name='my_add')
def func1(a, b):
return a + b
# 后台定义变量
i = 1
# 前台
{% load mytags %}
<p>{{ i|myadd:1 }}</p> # 这时前台页面会显示结果:2
自定义标签
可以定义多个参数(数量无限制),前端使用{% xxx %}进行调用,简单的例子
# 后端
@register.simple_tag(name='my_tag')
def func2(a, b, c, d, e)
return f'{a}-{b}-{c}-{d}-{e}'
# 前端使用
{% load mytags %} # 导入模块
{% my_tag 'Tom' 'Json' 'Maria' 'Jerry' 'Rose' %} # 使用标签,就是@register.simple_tag(name='my_tag')里面定义的name
# 页面返回结果为: Tom-Json-Maria-Jerry-Rose
inclusion_tag
- 它是一个局部的html代码。前端调用时,会通过后台函数执行,函数执行完后,会将结果传给一个html页面,最终再将html页面传回前端显示。
- 此功能专门用来生成部分html代码,再给到前端展示。
# 1. 创建一个html页面:menu.html
@register.inclusion_tag('menu.html', name='my_menu')
def func3(n):
html = []
for i in range(n):
html.append('<li>第%s页</li>'%i)
return locals()
# 2. 在menu.html中定义
<ul>
{% for liStr in html %}
{{ liStr|safe }}
{% endfor %}
</ul>
# 3. 在前端使用
{% load mytags %} # mytags是创建的py文件名
{% my_menu 10 %} # 这时就会产生10个li标签
模板的继承与导入
模板的继承
使用场景:
当多个页面布局相同,部分不同时,可以使用此项技术。
# 1. 前端页面定义好可以修改部分
{% block 区域名称 %}
可修改的html内容
{% endblock %}
# 2.子板继承母板后,还可以将block中的区域名称进行修改
{% extends 'xxx.html' %} # 1. 继承母板
{% block 区域名称 %} # 2. 指定需要修改的区域名称
{{ block.super }} # 可选项,在修改的同时继承母板的内容。也就是在母板此区域的基础上添加内容
# {{ block.super }} 可以多次使用,使用几次就是调用几次母板定义在“区域名称”中的内容
# 这里是子板自己的内容,可以将母板中定义好的修改部分进行修改
{% endblock %}
建议:
母板中至少应该有三个区域
- 页面内容区
- CSS页面区
- script代码区
- 例子
母板:
子板:
{% extends 'index.html' %}
{% block content %}
<form action="">
<p>用户名
<input type="text">
</p>
<p>密码
<input type="text">
</p>
</form>
{% endblock %}
可以看到,继承母板内容,并只修改部分页面
block.super使用
{% extends 'index.html' %}
{% block content %}
{{ block.super }}
{{ block.super }} # 调用母板中这个content中的内容,可以调用多次
{{ block.super }}
<form action="">
<p>用户名
<input type="text">
</p>
<p>密码
<input type="text">
</p>
</form>
{% endblock %}
如图:
模板的导入(不常用)
使用场景:定义一个模板,之后可以在其他html中多次调用
# 1. 定义一个模板
<h1>我就是这个模板</h1>
# 2. 在正式页面中调用
{% include 'xxx.html' %}
例如:
# 1.新建一个模板html文件,名字为:test1.html,内容如下:
<h1>我就是这个模板</h1>
# 2. 其他html页面调用
{% extends 'index.html' %}
{% block content %}
{% include 'test1.html' %} # 在任意一个html中都可以调用,不是必须子板才能调用
{% include 'test1.html' %}
<form action="">
<p>用户名
<input type="text">
</p>
<p>密码
<input type="text">
</p>
</form>
{% endblock %}
效果图如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)