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())
  • 优缺点
  1. 方法一 优点:传值比较有针对性,需要什么传什么,有针对性,节省资源。 缺点:键值对编写繁琐,浪费时间
  2. 方法二 优点:传值比较方便,不需要挨个指定键值对。 缺点: 会传不必要的值到前端,浪费资源

模板语法之取值

语法{{ 数据值 }}

  • 取普通数据值
{{ 数据值 }}
  • 取字典或列表
# 后端定义
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 %}

建议:
母板中至少应该有三个区域

  1. 页面内容区
  2. CSS页面区
  3. 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 %}

效果图如下:

posted @   树苗叶子  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示