Django的模板系统主要内容有,变量,模板标签,过滤器,模板继承等
变量,在django模板系统中变量用{{}}来包裹,而模板标签则用{% %}包裹。
变量支持深度查询,通过“."来表示。它查询的顺序是:
- 字典查询
- 属性或者方法查询
- 数字索引查询
例如,当我们通过view将article传给模板时,经常要获取文章的发表时间,那么我们就要用到深度查询:article.publish_date
注意事项:
- 如果计算结果的值是可调用的(主要为上面的第2类,属性或者方法),它将被无参数调用,调用的结果被填充到模板中的变量,eg:name.lower,它不需要括号。
- 如果使用的变量不存在,模板系统会插入string_if_invalid选项的值,默认情况下为''空字符串,也可以自己设置。在settings.py中的TEMPLATES中的options后另起一行插入下面的内容,这样在调试时,就能在前端网页上看到非法的提示。
'string_if_invalid': 'INVALID EXPRESSION: %s'
标签
标签主要由{% %} 组成,例如{% for i in items %}, {% if %}等。
过滤器
django 模板中,通过过滤器可以改变变量的显示,主要使用形式为{{ value|filter_name:parameters}}, 使用管道符|来应用。
注意事项:
- 过滤器支持“链式”操作
- 过滤器可以接受参数,eg: {{article|truncatewords:30}}
- 过滤器参数包含空格的话,必须用引号包裹起来,eg:{{list|join:', '}}
- '|'管道符左右没有空格。
常用过滤器有:
default, 设定默认值
filesizeformat,设定人类可读的文件尺寸,如kb, mb,gb等
slice,切片,eg:{{value|slice:"2:-1"}}
date, 格式化时间,{{value|date: "Y-m-d H:i:s"}}
safe, Django模板默认会对html标签和js等语法标签等进行转义,这样是为了安全考虑。所以可以通过safe告诉这段代码是安全的,不必转义。{% autoescape %} {% end escape %} 达到相同的效果。
truncatechars, 截断字符,字符串后面会以省略号结尾。
truncatewords, 截断单词。
cut,移除给定变量中的指定字符,eg: {{value|cut:' '}}移除所有的空格。
join,使用字符串连接列表,eg: {{list|join:','}}
timesince,将日期格式设为自该日期起的时间,一般有两部分组成,如:“4天”, “6小时”
timeuntil,从现在开始直到给定日期的时间。
模板继承:{% extend 'base.html' %}, {% include 'nav.html' %}
模板继承的作用类似于模板中的变量,由一个个的{% block %}来实现. {% extend %} 必须写在扩展的网页的开关部分,
例如,base.html
{% load staticfiles %}
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="shortcut icon" href="{% static "images/andy.png" %}"/>
{% block title %}
<title> Andy's blog </title>
{% endblock title %}
<!--css文件 -->
{% block custom_css %}
{% endblock custom_css %}
<script src="{% static 'js/jquery-3.3.1.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"/>
<link rel="stylesheet" href="{% static 'css/base.css' %}"/>
<!--js文件 -->
{% block custom_js %}
{% endblock custom_js %}
</head>
<body>
<div class="container main-body">
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="{% url 'blog:blog-home' %}">Home</a></li>
<li><a href="#">Scrapy</a></li>
<li><a href="#">Fund</a></li>
{% block search %}
<!--搜索框 -->
{% endblock search %}
</ul>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<!--左边栏 -->
{% block left_panel %}
{% endblock left_panel %}
<!--主要内容 -->
{% block content %}
{% endblock content %}
<!-- 分页 -->
{% block custom_paginator %}
{% endblock custom_paginator %}
</div>
<!--页脚 -->
{% block footer %}
<div class="footer">
Designed by ® Andy
</div>
{% endblock footer %}
</body>
base.html中写了很多 {% block %}, 这样在home 网页中 {% extends %},并且要用部分新的内容来替换base页面中的block,如果没有写新的block则会使用base中的内容。
与之对应的是 {% include %}, 它的作用是把另一个网页拿到当前位置来填充。
如果你想在父模板的block基础上添加新的内容,则使用block.super
<!--左边栏 -->
{% block left_panel %}
{{ block.super }}
<p>新的标签</p>
{% endblock left_panel %}
上面include的 实现了某一小功能的 页面称为 组件。与插件的区别是,插件更多的是封闭某一功能的函数。
自定义标签和过滤器
在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
在app中创建teamplatetags模块(模块名不能自定义)
创建任意.py文件,eg: my_tags.py
from django import template
register = template.Library() #register的名字是固定的,不可改变
@register.filter
def filter_multi(v1,v2):
return v1 * v2
@register.simple_tag #和自定义filter类似,只不过接收更灵活的参数,没有个数限制。
def simple_tag_multi(v1,v2):
return v1 * v2
使用时在网页中引入自定义的标签
{% load my_tag %}
# num=12
{{ num|filter_multi:2 }} #24
{% simple_tag_multi 2 5 %} 参数不限,但不能放在if for语句中