模板语法
1.模板语法的简介
模版语法可以将后端的内容传递给HTML页面,实现前端数据的动态展现,十分方便。
2.模板语法传值
在Django框架中,模板语法非常强大,可以将Python语法中各种字符类型,函数,类等内容传递到HTML页面,下面就来详细说明,首先需要了解的是传递模板语法的格式,模板语法按照传递的对象类型不同,传递的方式也有所不同
(1) 变量相关的数据
- 传递的方法
{{}} # 在双花括号内传递想传递的内容
- 可传递的内容
"""可传递的内容:整型,浮点型,字符串,列表,字典,元组,集合,布尔值"""
# 后端
def test(request):
i = 1
l = 1.1
o = [1, 2, 3]
v = {'key':123}
e = (1, 2, 3)
y = True
f = {1, 2, 3}
r = '你好呀'
return render(request, test.html, locals())
# html页面
<p>{{ i }}</p>
<p>{{ l }}</p>
<p>{{ o }}</p>
<p>{{ v }}</p>
<p>{{ e }}</p>
<p>{{ y }}</p>
<p>{{ f }}</p>
<p>{{ r }}</p>
# 浏览器展示
1
1.1
[1, 2, 3]
{'key':123}
(1, 2, 3)
True
{1, 2, 3}
'你好呀'
补充说明
- Django模版语法的取值是固定的格式 ,只能采用“句点符” . ,可以取列表中的值,也可以取字典中的值,但是只能用 . ,索引,get取值都不可以
(2) 逻辑相关的数据
- 传递的方法
{%%} # 在花括号加%内传递相关的内容
- 可传递的内容
"""可传递的内容:函数,类,对象,类与对象中的变量和方法"""
# 后端内容
def test(request):
def func():
return '我是Django妹子'
def error(x):
return '我无法被传递'
class MyClass(object):
def get_self(self):
return 'self'
@staticmethod
def get_func():
return 'func'
@classmethod
def get_class(cls):
return 'cls'
def __str__(self):
return '我能被打印么?'
obj = MyClass()
return render(request, 'test.html', locals())
# 前端代码
<p>{% func %}</p>
<p>{% MyClass %}</p>
<p>{% obj %}</p>
<p>{% MyClass.get_self %}</p>
<p>{% MyClass.get_func %}</p>
<p>{% MyClass.get_class %}</p>
<p>错误展示{% error %}</p>
# 浏览器效果展示
我是Django妹子
我能被打印么?
<app01.views.index.<locals>.MyClass object at 0x10c23a438>
<app01.views.index.<locals>.MyClass object at 0x10c1c1358>
self
func
cls
错误展示 # 传参的函数,无法被执行
补充说明:
- 对象被展示到html页面上 就类似于执行了打印操作也会触发__str__方法
- 针对函数名和类名,Django内部能够自动判断出当前的变量名是否可以加括号调用,如果可以就会自动执行
- 传递函数名会自动加括号调用,但是模版语法不支持给函数传额外的参数
- Django模版语法的取值是固定的格式 ,只能采用“句点符” . ,可以点类中变量,也可以点方法
3.模版语法之过滤器
(1) 过滤器的简介
过滤器就类似于模版语法的内置方法
(2) 过滤器的格式
{{数据|过滤器:参数}}
(3) 过滤器的种类
Django中内置的过滤器有60多个,今天介绍其中常用的十一个
功能 | 过滤器 | 参数 | 功能补充介绍 |
---|---|---|---|
统计长度 | length | — | 统计长度 |
数据为假设定默认值 | default | 任意设定 | 数据为真,则展示数据本身。数据为假,展示default后面的参数 |
转换文件大小 | filesizeformat | — | 能将文件的大小转换成合适单位的数据 |
日期格式化 | date | 'Y-m-d H:i:s' | 能将不易看懂的日期格式转换成用户容易看懂的数据 |
切片操作 | slice | 索引加步长 | 支持步长操作 |
切取字符 | truncatechars | 指定位数 | 包含三个点 |
切取单词 | truncatewords | 指定位数 | 按照空格切,不包括三个点,中文,英文都是按照空格切 |
移除特定的字符 | cut | 指定特定字符 | 切除指定的字符 |
拼接操作 | join | 指定特定字符 | 可以指定拼接符号拼接 |
拼接操作/加法 | add | 指定数字或字符串 | 可以加数字,可以加字符串 |
转义 | safe | — | 对于后端写的前端代码,如果前端想展示出效果,加这个参数 |
4.模板语法之标签
(1) 模板语法标签的本质
标签的本质就是一堆逻辑,包括for循环,if判断等
(2) for循环的使用
- for循环的使用
# 后端
def home(request):
l = [1, 2, 3]
return render(request, 'home.html', locals())
# html页面
{% for i in l %}
<p>{{ i }}</p>
{% empty %}
<p>如果可迭代对象里面没有东西,浏览器会显示这句话</p>
{% endfor %}
# 浏览器效果
1
2
3
"""强烈注意,empty 并不是for循环结束了才打印,而是可迭代对象为空时打印,而且empty就只是一个,不像for和if都是一组"""
- forloop变量的介绍:forloop是模板语法里面自带的一个变量
# 后端
def home(request):
l = [1, 2, 3, 4, 5]
return render(request, 'home.html', locals())
# html页面
{% for i in l %}
<p>{{ forloop }}</p>
{% endfor %}
浏览器效果展示如下:
- 补充:字典里的其他东西也是可以循环的,包括keys,values,items,都是可以循环的
# 后端
def home(request):
dict_a = {'a':1, 'b':2, 'c':3}
return render(request, 'home.html', locals())
# html
{% for i in dict_a%}
<p>{{ i }}</p>
{% endfor%}
{% for i in dict_a.keys%}
<p>{{ i }}</p>
{% endfor%}
{% for i in dict_a.values%}
<p>{{ i }}</p>
{% endfor%}
{% for i in dict_a.items%}
<p>{{ i }}</p>
{% endfor%}
# 浏览器展示
a
b
c
a
b
c
1
2
3
('a', 1)
('b', 2)
('c', 3)
(3) if判断的使用
if判断的使用
# 后端
def home(request):
a = False
b = 0
c = '我就是我,不一样的烟火'
return render(request, 'home.html', locals())
# html页面
{% if a %}
<p>{{ a }}</p>
{% elif b %}
<p>{{ b }}</p>
{% else %}
<p>{{ c }}</p>
{% endif %}
# 浏览器效果
我就是我,不一样的烟火
(4) for循环与if判断的结合
# 后端
def home(request):
a = [2, 3, 5]
b = [1, 2, 3]
c = '我就是我,不一样的烟火'
return render(request, 'home.html', locals())
# html页面
{% for i in a %}
{% if i in b %}
<p>我{{ i }}在{{ a }}和{{b}}里面</p>
{% else %}
<p>我{{ i }}在{{ a }}里,但不在{{ b }}里面</p>
{% endif %}
{% endfor %}
# 浏览器效果
我2在[2, 3, 5]和[1, 2, 3]里面
我3在[2, 3, 5]和[1, 2, 3]里面
我5在[2, 3, 5]里,但不在[1, 2, 3]里面
(5) with方法
with是用来起别名的一个方法,当比较长的数据在模板语法中频繁被使用的时候,重复写起来就显得非常麻烦,所以这时候可以起一个比较简短的名字,写起来就非常地方便
# 后端
def home(request):
l = [[1, 2, [1, 2, 3]], 3]
# html页面
{% with l.0.2.0 as a %}
<p>{{ a }}</p>
<p>{{ l.0.2.0 }}</p>
{% endwith %}
# 浏览器展示
1
1
5.自定义过滤器,标签,inclusion_tag
Django框架不仅自带很多的过滤器,标签等方法,还提供了用户自定义过滤器标签的服务,下面就来详细介绍自定义的方法。
(1) 自定义过滤器和标签
自定义过滤器和标签一共分为四步
- 第一步:在应用下创建一个名字必须为templatetags的文件夹
- 第二步:在templatetags文件夹下创建一个名称的mytag.py文件(这个py文件名可以任意取)
- 第三步:在py文件中书写以下代码
from django import template
register = template.Library() # 每个单词都不能写错
- 第四步:自定义过滤器和标签
@register.filter(name='my_sum') # 自定义过滤器
def su(a, b):
return a + b
@register.simple_tag(name='decorate')
def my_decorate(a, b, c):
return '***%s***%s***%s***' % (a, b, c)
- 第五步:使用过滤器和标签
# html页面
{% load my_tag %} # 导入文件
<p>{{ n|b:'3' }}</p> # n为后端常量,本案例中n=1
<p>{% my_decorate a b c %}</p>
{% load mytag %}
<p>{{ n|my_sum:3 }}</p>
<p>{% decorate 1 2 3 %}</p>
# 浏览器展示
4
***1***2***3***
重点说明
- 过滤器放在{{}}中,千万不能用错了
- 标签放在{% %}中,千万不能用错了
- 过滤器最多只能传递两个参数
- 标签可以传递多个参数
- 引入的过滤器名和标签名都是定义时,装饰器里面name的名字,不是函数的名字,千万不要搞错了
- @register.filter(name='') ,@register.filter(name=''),这两装饰器得牢记
- from django import template
register = template.Library() 这两句话牢记
(2) 自定义 inclusion_tag
- inclusion_tag的作用
当html页面某个地方需要传入参数才能动态地渲染出来,而且在多个地方需要使用到该局部, 那么就可以考虑将其做成inclusion_tag,这样以后,页面再使用的时候就非常方便
-
自定义inclusion_tag内部原理
-
inclusion——tag的制作方法
先定义一个方法,在页面上调用该方法 并且可以传值,该方法会生成一些数据然后传递给一个html页面,之后将渲染好的结果放到调用的位置
# 在mytag.py文件中定义该方法
@register.inclusion_tag('aim.html') # 'aim.html'是待作用的html页面
def aim(n):
data = ['第{}题'.format(i) for i in range(n)]
return locals()
# aim.html页面的代码
<ul>
{% for m in data %}
<li>{{ i}} </li>
{% endfor %}
</ul>
# 引用函数是aim的inclusion_tag页面的代码
{% load mytag %}
{% aim 4%}
# 浏览器展示
第0题
第1题
第2题
第3题
6.模板的继承
模板的继承的含义是指,对于某些网站来说,假如其中的很多页面样式保持不变,反复写重复的代码就显得非常麻烦,所以就可以写好模板后,其他页面继承这个模板,然后做局部的修改,具体的操作分为三个部分,模板的编写,子页面的编写
对于模板来说,里面的内容分为两部分,子模版直接继承无法修改的内容,子模版继承后可以直接修改的地方。对于直接继承的内容模板无需做特殊处理,而对于继承后可修改的地方需要做特殊处理。一般说来,将模板中需要修改的地方分成三块,js部分,content部分,以及css部分。但是三者的处理方式都一样,就是将可以修改的内容填写在以下的语法中:
- 模版语法
{% block 模块名 %}
模板内容
{% endblock %}
- 子页面语法
{% extends 模板html %}
{% block 模块名 %}
子页面内容
{% endblock %}
7.模板的导入
将页面的某一个局部当成模块的形式导入,导入的方法如下
{% inlude 'xxx.html' %}