模板层
一、模板介绍
在视图中硬编码HTML的弊端
-
要想修改页面设计就得修改Python代码
-
加大排错和诊断程序代码的难度
-
术业有专攻,能提高工作效率。
因此我们将页面的设计和Python代码分开,结果更简洁,更易于维护,对此我们使用Django的模板系统。
Django 模板是一些文本字符串,作用是把文档的表现与数据区分开。模板定义一些占位符和基本的逻辑(模板标签),规定如何显示文档。通常,模板用于生成 HTML,不过 Django 模板可以生成任何基于文本的格式。
模板系统的设计目的是呈现表现,而不是程序逻辑。
二、模板语法
-
-
一对花括号和百分号包围的文本(如 {% if 条件 %})是模板标签。标签的定义相当宽泛:只要能让模板系统“做些事”的就是标签。
-
过滤器是调整变量格式最为便利的方式,过滤器使用管道符号(|)依附。如{{date|date:‘Y-m-d’}}就是使用参数指定的格式格式化日期。
三、变量详解
将数据从后端传给前端页面的方法
# 第一种 return render(request,'index.html',{'n':n}) # 第二种 return render(request,'index.html',locals()) # 将当前所在的名称空间中的名字全部传递给前端页面
python所有数据类型都可以传到前端。
传函数名:传过来会自动加括号调用,显示返回值。
传对象:对象内存地址,等于后端print对象,可通过点方法获取属性或调用方法
注:模板语法不能传参,若函数或方法有参数,不能使用
端获取后端传过来的容器类型的内部元素,通过 句点符 .,
. 数字
,数字就是索引,字典就是用.key。
模板语法的注释方式不会展示到前端页面:{#注释#}
四、过滤器详解
语法:{{后端传来的数据 | 过滤方法}},前面的值会当做第一个参数传递给|后面的函数
统计字符串或列表长度:length 传入的值是空则返回default后面默认参数:default:'传值为空' 将数字格式化成表示文件大小的单位:filesizeformat 格式化时间(不要加百分号):date:'Y-m-d' 切片:slice:'0:8:2' 截取固定的长度的字符串,三个点也算:truncatechars:长度 按照空格截取文本内容:truncatewords:空格数 给数字加一个值,如果第一个参数是字符串,会默认全转成字符串进行拼接:add 取消转义:默认不会识别标签语法,防止危险攻击。取消转义后能识别 前端 safe 后端 from django.utils.safestring import mark_safe x = mark_safe('<h1>我是h1标签</h1>')
五、标签详解
for循环(可嵌套)
<!--{% for %} 标签用于迭代序列中的各个元素。句法是 for X in Y,其中 Y 是要迭代的序列,X 是单次循环中使用的变量。每次迭代时,模板系统会渲染 {% for %} 和 {% endfor %} 之间的内容。--> <ul> {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} </ul>
empty
<!-- for 标签支持一个可选的 {% empty %} 子句,用于定义列表为空时显示的内容 --> {% for athlete in athlete_list %} <p>{{ athlete.name }}</p> {% empty %} <p>There are no athletes. Only computer programmers.</p> {% endfor %}
forloop
在 {% for %} 循环内部,可以访问一个名为 forloop 的模板变量。这个变量有几个属性,通过它们可以获知循环进程的一些信息:
-
forloop.counter 的值是一个整数,表示循环的次数。值从 1 开始。
-
forloop.counter0 与 forloop.counter 类似,值从0开始。
-
forloop.revcounter 的值是一个整数,表示循环中剩余的元素数量。第一次循环时,值是序列中要遍历的元素总数。最后一次循环时值为 1。
-
forloop.revcounter0 与 forloop.revcounter 类似,不过索引是基于0。
-
forloop.first 是个布尔值,第一次循环时为 True,其余为False。
-
forloop.last 是个布尔值,最后一次循环时为 True,其余为False。经常用它在一组值之间加分隔符号。
-
在嵌套的循环中,forloop.parentloop 引用父级循环的 forloop 对象
-
forloop 变量只在循环内部可用。
<!--{% if %} 计算变量的值,如果为真(即存在、不为空,不是假值),模板系统显示 {% if %} 和 {% endif %}之间的内容--> {% if today_is_weekend %} <p>Welcome to the weekend!</p> {% endif %} <!--{% else %} 标签是可选的--> {% if today_is_weekend %} <p>Welcome to the weekend!</p> {% else %} <p>Get back to work.</p> {% endif %} <!-- if 标签还可以有一个或多个 {% elif %} 子句 --> {% if athlete_list %} Number of athletes: {{ athlete_list|length }} {% elif athlete_in_locker_room_list %} <p>Athletes should be out of the locker room soon! </p> {% elif ... ... {% else %} <p>No athletes. </p> {% endif %}
{% if %} 支持使用 and、or 或 not 测试多个变量,或者取反指定的变量,但在if标签中使用括号是无效的语法。若要指明优先级,应该使用嵌套的{% if %}标签或者考虑在模板外部执行逻辑,然后通过模板变量传入结果。
多次使用相同的逻辑运算符没问题,但是不能混用不同的运算符。
六、自定义相关
前戏
-
在应用名下新建一个名为templatetags文件夹(必须叫这个名字)
-
在该新建的文件夹内新建一个任意名称的py文件
-
在该py文件中需要固定写下面两句代码
from django import template register = template.Library()
-
在前端页面{%load 新建的py文件%}
自定义过滤器
# 后端 @register.filter(name='XBB') def index(a,b): return a+b # 前端 {{ 666|XBB:8 }}
自定义标签
# 后端 @register.simple_tag def plus(a,b,c): return a+b+c # 前端 {% plus 1 2 3 %}
自定义inclusion_tag
# 自定义inclusion_tag @register.inclusion_tag('login.html',name='login') def login(n): l = [ '第%s项'%i for i in range(n)] return {'l':l} # login.html <ul> {% for foo in l %} <li>{{ foo }}</li> {% endfor %} </ul> # 调用 {% login 5 %}
七、模板的继承与导入
继承
首先需要在被继承的模板中划分多个区域 {% block 给区域起的名字 %} {% endblock %} 通常情况下一个模板中应该至少有三块 {% block css %} 页面css代码块 {% endblock %} {% block js %} 页面js代码块 {% endblock %} {% block content %} 页面主体内容 {% endblock %} 子板继承模板 先继承模板所有的内容 {% extends 'home.html' %} 然后根据block块的名字修改指定区域的内容 {% block 想修改区域的名字 %} 修改 {% endblock %}
导入
# 将一段html当做模块的方式导入到另一个html展示 {% include '想导入的html文件名' %}