10 模板层
模板语法和变量
模板语法:
- {{}} 渲染变量用
- {%%} 渲染标签用
渲染变量{{ }}
- 深度查询,局点符
return render(request,"app04template/index.html",{"name":name,"age":age,"ls":ls,"info":info,"b":b,"p1":p1,"p2":p2,"person_list":person_list}) #等同于上面传值方法,传值较多可直接用locals()方法 return render(request,"app04template/index.html",locals())
tml页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>app04template</title> </head> <body> <h1>{{ name }}</h1> <h1>{{ age }}</h1> <h1>{{ ls }}</h1> <h1>{{ info }}</h1> <h1>{{ b }}</h1> <h1>{{ p1 }}</h1> <h1>{{ p2 }}</h1> <h1>{{ person_list }}</h1> </body> </html>
- 用句点号进行深度查询,列表用.index方式查询的时候,从0开始
<h1>{{ name }}</h1> <h1>{{ age }}</h1> <h1>{{ ls }}</h1> <h1>{{ ls.1 }}</h1> <h1>{{ info }}</h1> <h1>{{ info.a }}</h1> <h1>{{ b }}</h1> <h1>{{ p1 }}</h1> <h1>{{ p2 }}</h1> <h1>{{ person_list }}</h1> <h1>{{ person_list.1.name }}</h1> <h1>{{ person_list.1.age }}</h1>
渲染标签{% %}
模板过滤器
把视图传过来的数据进行过滤,修饰等之后再进行显示,用竖杠(|)方法
语法:
{{ obj|filter_name:param }}
用过滤器修改日期显示格式
未用过滤器效果
添加date过滤器
<p>{{ now|date:"Y-m-d" }}</p>
过滤器调整时间显示格式
默认过滤器:
- default:如果一个变量为空,则给定默认值,参数为给定的默认值
- length:返回变量长度,只对列表和字符串生效
- filesizeformat:将文件大小格式化成可读的显示方式,如10KB,5.2MB等
- date:格式化时间显示方式,参数为Y-m-d
- slice:对数据进行切片,如value|slice:"2:-1"
- fruncatechars:对字符串按指定长度进行截断,多余部分显示为...,如value|truncatechars:9
- fruncatewords:按单词进行截断
- safe:为了安全起见,django的模板中会对HTML标签和JS等语法标签进行转义,不希望被转义,则用safe过滤器,无参数
- add:加法过滤器,加上指定参数,如number|add:100
- upper:小写转大写
个别字段需要展示html,无需前台用safe标签过滤器,可以用mark_safe
from django.utils.safestring import mark_safe
return mark_safe('<input type="checkbox" name="pk" />')
模板标签
for标签
forloop.counter记录遍历序号
<body> <p>----------for标签语法---------</p> <p>遍历列表</p> {% for i in ls %} <p>{{ i }}</p> {% endfor %} <p>遍历字典</p> {% for i in info %} <p>{{ i }}</p> {% endfor %} <p>遍历对象列表</p> {% for p in person_list %} <p>{{ forloop.counter }} {{ p.name }}</p> {% endfor %} </body>
for ...empty标签
for标签带有一个可选的{% empty %}从句,以便在给出的组是空或者未找到时有所操作
<body> {% for person in person_list %} <p>{{ person.name }}</p> {% empty %} <p>no person here</p> {% endfor %} </body>
if标签
<body> {% if user %} <p>欢迎{{ user }}登录</p> {% else %} <p>登录 注册</p> {% endif %} </body>
with标签
用一个简单的名字缓存一个复杂的变量
<body> {% with person_list.1.name as pname %} {{ pname }} {% endwith %} </body>
scrf_token标签
提供跨域请求保护机制
模板中添加scrf_koten标签
<form action="{% url 'app03:index' %}" method="post"> {% csrf_token %} <input type="text" name="name" placeholder="姓名"> <input type="text" name="age" placeholder="年龄"> <input type="submit" value="提交"> </form>
自定义标签和过滤器
- 在settings中注册app,INSTALLED_APPS列表中添加模块名
- 在app下新建templatetags模块,模块名不能改
- 创建任意py文件写过滤器
from django import template register=template.Library() #自定义乘法过滤器 @register.filter def multi_filter(x,y): return x*y
- load自定义模块后即可使用
<body> <p>自定义乘法过滤器</p> {% load myTagFilter %} {{ i|multi_filter:10 }} </body>
- 自定义乘法标签
#自定义乘法标签 @register.simple_tag def multi_tag(x,y): return x*y
- 使用过滤器,如果乘以10后大于200,则显示200,否自显示自身
<p>自定义乘法过滤器</p> {% load myTagFilter %} {{ i|multi_filter:10 }} {% if i|multi_filter:10 > 200 %} <p>200</p> {% else %} <p>{{ i }}</p> {% endif %}
- 代码中调用乘法标签,记得load
<body> <p>自定义乘法标签</p> {% multi_tag 10 10 %} </body>
过滤器和标签区别:
- 过滤器只能接收两个参数
- 标签可以传递多个参数
- 标签不能放置到if等判断语句
继承标签
include 从一个html页面中导入另一个html文件
<body> {% include "advertise.html" %} </body>
继承:
- 创建模板页面,包含导航等公用区域,在被填充区域添加block盒子,一个html页面中可以预留多个盒子
{% block con %} {% endblock %}
- 创建子页面,用extends方法继承,重写block con盒子内容。
{% extends "base.html" %}
{% block con %}
<!--子页面用来填充父页面con部分的html代码-->
{% endblock %}
从一个页面中导入另一个文件的部分区域,即重写父盒子的block区域
保留父盒子内容,子盒子的block前面加{{ block.super }},
注意:
- extends必须放置在首行
- 盒子尽量多预留,并写入默认值,没有被重写则显示默认内容
inclusion_tag注册HTML代码
一个模板中有一块数据是在之后的每个页面中出现的。
方式一:在每个视图函数中返回对应数据
方式二:inclusion_tag方法,让模板通过“过滤器”自动获取数据和渲染,实现数据和代码重用
- 在app下新建一个templatetags的py包,注册后需要重启服务,否则提示not registered
- 在包中自己创建一个py文件,用来写“过滤器”
- 在py文件中导入需要的模块,这里需要的模块包含获取数据所需模块
- 定制标签模板,用来渲染自己的数据
<div> <div class="panel panel-warning"> <div class="panel-heading">我的标签</div> <div class="panel-body"> {% for tag in tag_list %} <p><a href="/{{ username }}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p> {% endfor %} </div> </div> <div class="panel panel-danger"> <div class="panel-heading">随笔分类</div> <div class="panel-body"> {% for cate in cate_list %} <p><a href="/{{ username }}/category/{{ cate.0 }}">{{ cate.0 }}({{ cate.1 }})</a></p> {% endfor %} </div> </div> <div class="panel panel-danger"> <div class="panel-success">随笔归档</div> <div class="panel-body"> {% for date in date_list %} <p><a href="/{{ username }}/archive/{{ date.0 | date:'Y-m' }}">{{ date.0 | date:'Y-m' }}({{ date.1 }})</a></p> {% endfor %} </div> </div> </div>
- 自定义获取数据的方法,返回字典数据,这个字典类似渲染模板的字典
- 装饰自定义的方法,并给装饰器传入html模板,这个模板用来渲染自定义方法返回的数据
@register.inclusion_tag('classification.html') def get_classification_style(username): user = models.UserInfo.objects.filter(username=username).first() print(user) blog = user.blog cate_list = models.Category.objects.filter(blog=blog).annotate(c=Count('article__nid')).values_list('title', 'c') tag_list = models.Tag.objects.filter(blog=blog).values('pk').annotate(c=Count('article__title')).values_list('title', 'c') date_list = models.Article.objects.filter(user=user).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('nid')).values_list('month', 'c') return {'username':username,'blog': blog, "cate_list": cate_list, "tag_list": tag_list, 'date_list': date_list}
- 在html中像调用过滤器一样调用,返回的是被渲染过的html标签。即在html中添加html标签
这里的username即是自定义方法所需参数