django 模板层
django 模板层
模板层所对应的文件夹是templates,它的作用是存放html文件。
后端通过代码将数据发送到前端,前端通过模板语法将数据展示到html页面。
一、后端向前端传送数据
有两种传值方式:
① 指名道姓传(只传需要的)
② 一次性全部传过去(locals方法,需不需要都传过去)
def show_data(request): str1 = 'hello' int1 = 17 dict1 = {'name': 'tom', 'age': 21} list1 = [1, 2, 3, 4, 5] tuple1 = (6, 7, 8, 9, 10) set1 = {'a', 'b', 'c', 'd', 'e'} bool1 = True float1 = 12154.54 """第一种方式:指名道姓传(只传需要的)""" return render(request, 'show_data.html', {'str1': str1, 'int1': int1, 'dict1': dict1, 'list1': list1, 'tuple1': tuple1, 'set1': set1, 'bool1': bool1, 'float1': float1 }) """第二种传值方式:locals()方法,一次性全部传过去(需不需要都传过去)""" # return render(request, 'show_data.html', locals())
二、模板语法
1、模板语法注释
{# 模板语法注释 #}
2、模板语法取值 {{ }}
django模板语法取容器类型(list、tuple、dict、set)数据只有一种操作方式 句点符.
前端代码
<h2>前端模板语法取值</h2> <p><b>字符串取值</b></p> <p>{{ str1 }}</p> <p><b>整型取值</b></p> <p>{{ int1 }}</p> <p><b>字典取值</b></p> <p>{{ dict1 }}</p> <p>{{ dict1.name }}</p> // 句点符取值,通过属性名取 <p>{{ dict1.age }}</p> <p><b>列表取值</b></p> <p>{{ list1 }}</p> <p>{{ list1.0 }}</p> // 句点符取值,通过索引取 <p>{{ list1.1 }}</p> <p>{{ list1.2 }}</p> <p>{{ list1.3 }}</p> <p>{{ list1.4 }}</p> <p><b>元组取值</b></p> <p>{{ tuple1 }}</p> <p>{{ tuple1.0 }}</p> // 句点符取值,通过索引取 <p>{{ tuple1.1 }}</p> <p>{{ tuple1.2 }}</p> <p>{{ tuple1.3 }}</p> <p>{{ tuple1.4 }}</p> <p><b>集合取值</b></p> <p>{{ set1 }}</p> <p><b>布尔值取值</b></p> <p>{{ bool1 }}</p> <p><b>浮点型取值</b></p> <p>{{ float1 }}</p>
3、模板语法过滤器
过滤器 | 左边的会当做过滤器的第一个参数,过滤器右边的会当做第二个参数
① |length 计算长度
{{ str1|length }} # 求str1的长度
② |add 加法运算,既可以做数字加法,也可以字符串拼接,若无法相加,返回空
{{ int1|add:10 }} # 将int1与10相加
③ |default 判断是否为空
{{ a|default:'我是默认值' }} # 判断a是否是空,若不为空,返回a,若为空,返回后面的'我是默认值'
④ |truncatechars:数字 截取多少个字符,三个点也算
{{ str1:truncatechars:2 }} # 截取两个字符
⑤ |truncatewords:数字 截取多少个单词,三个点不算(按照空格来截取)
{{ str2:truncatewords:5 }} # 截取5个单词
⑥ |slice 切片操作
{{ str3|slice:'0:8:2' }} # 切取str3的0-8字符,步长为2
⑦ |date 转换日期
{{ time1|date:'Y年/m月/d日' }}
⑧ |filesizeformat 获取文件大小
{{ file_size|filesizeformat }} # 计算file_size的大小
4、模板语法转义
|safe 转义
res|safe
前端代码不一定非要在前端写,可以在后端写好之后丢给前端来渲染
后端代码:
def show_data(request): res = '<h1>hello python world<h1>' return render(request, 'show_data.html', {'res': res})
前端代码:
<p>{{ res|safe }}</p>
效果图:
总结:前端代码不一定非要在前端页面写,可以在口段写好传递给前端页面使用,这样的话就可以使用到后端更多的逻辑语法
5、模板语法之标签(逻辑相关)
1)for循环语法(前端 输入for,然后按Tab键自动补全)
{% for foo in list1 %} <p>{{ foo }}</p> {% endfor %}
{% for foo in list1 %} <p>{{ forloop }}</p> {% endfor %}
{% for foo in list1 %} {% if forloop.first %} <p>这是第一次,打印出{{ foo }}</p> {% elif forloop.last %} <p>这是最后一次,打印出{{ foo }}</p> {% else %} <p>{{ foo }}</p> {% endif %} <p>打印{{ foo }}之后都会打印我</p> {% endfor %}
2)当一个值获取的步骤非常繁琐,但是又需要在很多地方用到,我们可以用到起别名的方式来简化代码(别名只能在with内使用)
后端代码:
def show_data(request): dict1 = {'account': ['tom', {'username': ['tank', 'jack']}]} return render(request, 'show_data.html', {'dict1': dict1})
前端代码:
{% with dict1.account.1.username.1 as name %} <p>{{ dict1.account.1.username.1 }}</p> <p>{{ name }}</p> {% endwith %}
效果图:
6、自定义过滤器、标签、inclusion_tag
前期准备工作:
① 在应用名下新建一个名字必须为templatetags文件夹
② 在该文件夹内新建一个任意名字的py文件
③ 在该文件内必须先写以下两句代码
from django.template import Library
register = Library() # 生成一个Libray对象
1)自定义过滤器(只能传两个参数)
templatetags\mytags.py后端
from django.template import Library register = Library() # 自定义过滤器 @register.filter(name='def_sum') def num(a, b): return a+b
show_data.html前端展示页
{% load mytags %} <h2>{{ 10|def_sum:20 }}</h2>
2)、自定义标签的使用(可传多个参数)
templatetags\mytags.py后端
# 自定义标签 @register.simple_tag(name='link_str') def xxx(a, b, c, d): return '%s-%s-%s-%s' % (a, b, c, d)
show_data.html前端展示页
{% load mytags %} <h2>{% link_str 1 2 3 'hello' %}</h2>
注意事项:自定义的过滤器可以在逻辑语句中使用而自定义标签不可以
3)、自定义inclusion_tag
templatetags\mytags.py后端
# 自定义inclusion_tag @register.inclusion_tag('demo2.html', name='def_inclusion') def demo(n): list1 = [] for i in range(n): list1.append(i) return locals()
demo2.html (inclusion_tag将后端代码传过来的值先放在第三方html页面demo.html中,然后将demo.html页面中的内容呈现在index.html前端展示页中)
<ul> {% for foo in list1 %} <li>{{ foo }}</li> {% endfor %} </ul>
show_data.html前端展示页
{% load mytags %}
{% def_inclusion 5 %}
三、模板的继承
某一个页面大部分区域都是公用的,那么这个页面就可以作为模板页面。当其他继承这个页面之后,只修改对应的区域代码即可,可减少代码量
模板页面通过block实现划定区域。
1、主页面代码
...
{#上面写公用页面代码#}
{% block content %}
...
{#中间写可被修改html代码#}
...
{% endblock %}
{#下面写公用页面代码#}
...
2、子页面继承
① 子页面中先导入整个模板(子页面任何代码都不需要,直接导入即可)
{% extends '模板主页面.html' %}
② 修改特定的区域 通过实现规划好的区域名称
{% block content %}
...
# 写子页面自己的html代码内容
...
{% endblock %}
3、模板继承规范
通常情况下,模板页面应该起码有三块区域
{% block css %}
{#主页面css代码#}
{% endblock %}
{% block content %}
{#主页面content代码#}
{% endblock %}
{% block js %}
{#主页面js代码#}
{% endblock %}
还支持子页面调用父页面(模板页面)对应区域的内容,并且可以无限次调用
{{ block.super }}
四、模板的导入
可以将提前写好的每一个前端页面组件(导航条、分页器、标签栏等等...)单独放一个html文件(这个html页面通常不是一个完整的页面,只是一个局部样式)作为页面组件模板存着,可以导入到其他的html页面中,方便使用。
导入方法:
{% include '页面组件模板.html' %}