django—模板层
1、模板语法
在html页面上,通过模板语法获取视图层传过来的值
两种书写格式:
{%%} # 逻辑相关
{{}} # 变量相关
2、模板传值
2.1 支持所有的Python基本数据类型
int,float,str,list,tuple,dict,set,bool
以字符串为例:
# views.py
class MyLogin(View):
def get(self,request):
return render(request,'login.html')
def post(self,request):
username = request.POST.get('username')
password = request.POST,get('password')
# 若验证通过,登陆成功
return render(request,'index.html',{'username':username})
# index.html
{{username}}
2.2 支持函数名、类名、对象
1、传函数名,不能传参数
2、传类名,不能传参数,可以调用类的属性
3、传对象,可以调用对象的属性
4、传函数名、类名等,在html页面上,模板语法会自动加括号调用
3、过滤器
变量相关,使用模板语法:{{}}
3.1 过滤器语法及注意事项
1、在django模板语法中,通过使用过滤器来改变变量的显示
2、过滤器的语法:{{变量|过滤器:过滤器参数}}
3、过滤器支持链式操作,一个过滤器的输出作为另一个过滤器的输入
4、过滤器参数包含空格时,必须用引号将参数括起来
5、|
左右没有空格
3.2 内置过滤器
过滤器 | 作用 | 示例 |
---|---|---|
default | 如果一个变量是false或者为空,使用给定的默认值, 否则,使用变量的值 |
`{{ value |
length | 返回值的长度,作用于字符串和列表 如果无法统计,默认返回0 |
`{{ value |
add | 加法运算,内部异常捕获 支持数字相加、字符串拼接、默认返回空字符串 |
`{{ value |
slice | 切片,顾头不顾尾,支持步长,不支持负索引 | `{{ value |
filesizeformat | 将文件大小格式化为一个易读的格式,如10KB | `{{ file_size |
truncatechars | 获取指定长度字符串,多余部分将被截断 截断部分将以 ... 显示,占3个长度 |
`{{ value |
truncatewords | 同truncatechars 被截断部分不做显示 |
`{{ value |
safe | 展示带有标签的文本,如:"<a href='#'>点我</a>" |
`{{ value |
3.3 前后端的转义
前端:safe过滤器
后端:使用模块mark_safe
from django.utils.safestring import mark_safe
res = mark_safe('<h1>dhada</h1>')
注意:
使用前后端的转义,意味着可以在后端写html代码
4、标签
逻辑相关:for循环、if判断、with、csrf_token
使用模板语法:{%%}
4.1 for循环
语法:
<!--以user_list为例,for循环创建一个无序列表-->
<ul>
{% for user in user_list %}
<li>{{ user.name }}</li>
{% endfor %}
</ul>
可用参数
参数名 | 说明 |
---|---|
forloop.counter |
当前循环的索引值(从1开始) |
forloop.counter0 |
当前循环的索引值(从0开始) |
forloop.revcounter |
当前循环的倒序索引值(从1开始) |
forloop.revcounter0 |
当前循环的倒序索引值(从0开始) |
forloop.first |
当前循环是不是第一次循环(布尔值) |
forloop.last |
当前循环是不是最后一次循环(布尔值) |
forloop.parentloop |
本层循环的外层循环 |
for ... empty
当for循环没有值的时候,执行
<!--以user_list为例,当user_list为空的时候,执行empty的语句-->
<ul>
{% for user in user_list %}
<li>{{ user.name }}</li>
{% empty %}
<li>空空如也</li>
{% endfor %}
</ul>
4.2 if判断
语法:
支持and 、or、==、>、<、!=、<=、>=、in、not in、is、is not
等运算符
<!--以user_list为例-->
<ul>
{% if user_list %}
用户人数:{{ user_list|length }}
{% elif black_list %}
黑名单数:{{ black_list|length }}
{% else %}
没有用户
{% endif %}
</ul>
4.3 with
1、定义一个中间变量,多用于给一个复杂的变量起别名
2、等号左右不能加空格
3、别名只能在with内起效
<!--以变量business.employees.count为例,可以在with内起别名为total-->
<!--使用等号起别名,注意等号两端不能有空格-->
{% with total=business.employees.count %}
{% endwith %}
<!--使用as起别名-->
{% with business.employees.count as total %}
{% endwith %}
4.4 csrf_token
用于跨站请求伪造保护
在页面的form表单里写上{% csrf_token %}
4.5 注释
语法:{##}
4.6 注意点
1、django模板语法不支持连续判断
<!--不支持以下用法-->
{% if a > b > c %}
...
{% endif %}
2、django模板语法中,属性的优先级大于方法
# views.py
def func(request):
dic = {'a':1, 'items':2}
return render(request,'func.html',{'data':dic})
# func.html
{{data.items}}
# 此时,在html中接收到的data是一个字典,字典有方法items(),同时又有名为items的key
# 两者的取值方式,都是data.items
# 由于模板语法中,属性优先级大于方法,所以结果为字典中的key值
5、自定义过滤器和标签
5.1 前提
1、在应用中新建一个名为templatetags的文件夹
2、在该文件夹内新建一个任意名称的py文件
3、在这个py文件中,写上下面的代码
from django.template import Library
register = Library()
完成之后,利用regeister来定义过滤器和标签
5.2 自定义过滤器
最多只能接收两个参数,跟内置过滤器一样
# regeister所在的py文件
@regeister.filter(name='xxx') # 使用语法糖自定义过滤器,并命名过滤器
def index(a,b): # 过滤器实际上就是一个函数,不过最多只能接收两个参数,跟内置过滤器一样
return a + b
# html文件
{% load xxx %} # 先加载过滤器
{{ 1|xxx:2 }} # 再使用过滤器
5.3 自定义标签
可以接收多个参数,以空格分隔
# regeister所在的py文件
@regeister.simple_tag(name='mytag')
def mytag(a,b,c,d):
return f'{a}#{b}#{c}#{d}'
# html文件
{% load mytag %} # 先加载标签
{% mytag 1 2 3 4 %}
5.4 注意点
自定义过滤器可以在逻辑语句中使用
自定义标签不可以
5.5 自定义inclusion_tag
1、是一个函数 能够接受外界传入的参数 然后传递给一个html页面
2、页面上获取数据 渲染 完成之后,将渲染好的页面 放到调用inclusion_tag的地方
当你需要使用一些页面组件的时候 并且该页面组件需要参数才能够正常渲染 你可以考虑使用inclusion_tag
# # regeister所在的py文件
@regeister.inclusion_tag('mytag.html',name='mytag')
def mytag(n):
l = []
for i in range(n):
l.append(f'第{i}项')
return locals() # 将l直接传递给mytag.html页面
# 任意的要使用的mytag组件的html页面
{% load mytag %} # 先加载组件
{% xxx 5 %} # 给组件传参数,渲染完成之后,放到调用的地方
6、模板的继承
1、再想要使用的html页面上,划定区域
2、继承之后,可以修改划定的区域内容,非划定的区域无法修改
6.1 划分可修改区域
语法:
{% block content %} <!--content为自定义的被划分区域的名字-->
被划分的区域
{% endblock %}
注意:
1、一般划分三种区域: css区域 html代码区域 js区域
2、block区域越多,页面的可扩展性越强
6.2 继承
继承语法:
{% extends 'home.html' %} <!--通过模板页面名继承模板页面-->
修改语法:
<!--继承之后,才能修改-->
{% block content %} <!--通过block区域名加载该区域-->
... <!--在此区域内重写或者修改block区域的html代码-->
{% endbolck %}
重用母板block区域的内容
{% block content %}
{{ block.super }} <!--沿用母板bolck的内容-->
...
{% endbolck %}
7、模板的导入
将html页面当作模块,直接导入使用
{% include 'home.html' %} <!--通过html文件名导入-->