django系列4.1--模版系统,过滤器,标签,模版继承,组件

django 模版系统

一. 语法

	{ { 变量 } }

	{% 表达式 %}

二. 变量

{ {变量名} }

深度查询据点符( . )在模版语言中有特殊的含义. 当模版系统遇到点(.) 查询顺序如下:

  1.字典查询

  2.属性或方法的查询

  3.数字索引查询

 

注意事项:

​ 1.如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。

​ 2.如果使用的变量不存在, 模版系统将插入 string_if_invalid 选项的值, 它被默认设置为’’ (空字符串) 。

 

views.py

def index(request):
	s = 'hello'
	lst = [1,2,3]
	dic = {"name":"tom","age":13}
	return render(request,'index.html',{"s":s,"lst":lst,"dic":dic})

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a>渲染的字符是{{ s }}</a>
<a>列表是{{ lst }}</a>
<a>字典中的name是{{ dic.name }}</a>
</body>
</html>

 

三.过滤器

  Django的模版语言中,用过滤器来修改变量的显示

语法:
使用过滤器来改变变量的显示

{{ value|filter_name:参数 }}
	value|default:"nothing" 	默认值
	value|length 				返回值的长度
	value|filesizeformat		将值格式化为一个可读的文件尺寸
	value|slice:"1:2" 			切片
	value|date:"Y-m-d H:M:S" 	格式化时间
	value|safe 					不用对value进行转义
	value|truncatechars:9 		截断字符串 这里的参数为9(6个字符串+3个省略号)
	value|truncatewords 		在一定数量的字后截断字符串, 是截多少个单词
	value|cut:' ' 				移除value中所有的与给出的变量相同的字符串
	list|join:',' 				就像python中的str.join(list)
	
	blog_date|timesince:comment_date 	将日期格式设为自该日期起的时间
	conference_date|timeuntil:from_date 测量从开始直到给定日期或日期时间的时间

管道符“|”来应用过滤器,需要注意:

  1.支持链式操作,一个过滤器的输出作为另一个过滤器的输入

  2.可以接受参数,{{content|trunctewords:10}} 表示显示content的前10个词

  3.参数若包含空格,必须用引号包裹,如{{list|join:’,’}}就是用逗号和空格连接一个列表中元素

  4.’|’管道符左右两边没有空格

django的模版语言提供了许多的内置过滤器,常用的有

 

default

​ 如果一个变量是false或者为空,使用给定的默认值.否则,使用变量的值.如果value没有传值或者值为空就会显示nothing

{{value|default:"nothing"}}

 

length

​ 返回值的长度,作用于字符串和列表,如value = [’a’,’b’,’c’,’d’]的话,就显示4,因为列表的长度为4

{{value|length}}

 

filesizeformat

​ 将值格式化为一个’人类可读的文件尺寸’,如(1GB,2.4MB等),如果value是len = 10511515,会显示10.0MB

{{value|filesizeformat}}

 

slice

​ 切片,字符串或其他可切片的数据类型,冒号左边为开始的索引,右边为结束的索引,-1表示切到倒数第一个

{{value|slice:"2:-1"}}

 

date

​ 格式化,如果value = datetime.datetime.now()

{{value|date:"Y-m-d H:i:s"}}

​ 关于时间日期的可用参数有很多,可以google查询

 

safe

{{value|safe}}

​ django模版进行渲染时会对HTML标签和JS等语法标签自动转义,防止用户提交时使用js,html代码破坏(防止xss攻击).为了防止这些内容被转义,使用safe来告诉django这段代码是安全的不必转义

 

views.py

def safe(request):
    s = '<a> 这里是a标签 </a>'
    return render(request,'safe.html',{"s":s})

safe.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ s|safe }}
</body>
</html>

 

truncatechars

​ 如果字符多于指定的字符数量,就会被阶段.截断后的字符串以可翻译的省略号序列(‘...’)结尾.

{{ value|truncatechars:9}}

​ 结果显示的三个省略号也是9个字符内的,就是6个字符+3个省略号.可以配合前端的点击事件展开

 

truncatewords

​ 在一定数量的字后截断字符串(截指定个数的单词),比如s = ’hello world’结果就是 hello ..…

{{value|truncatewords:3}}

 

cut

​ 移除value张红所有的与给出的变量相同的字符串

{{value|cut:''}}

​ 移除变量中所有的空格
​  

join

​ 使用字符串连接列表,{{list|join:’,’}}, 就像python中的str.join(list)
​ 

timesince

    将日期格式设为自该日期起的时间(例如,“4天,6小时”)。
    采用一个可选参数,它是一个包含用作比较点的日期的变量(不带参数,比较点为现在)。 例如,如果blog_date是表示2006年6月1日午夜的日期实例,并且comment_date是2006年6月1日08:00的日期实例,则以下将返回“8小时”:

{{ blog_date|timesince:comment_date }}

    分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回“0分钟”。

    分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回“0分钟”。

 

timeuntil

    类似于timesince,除了它测量从现在开始直到给定日期或日期时间的时间。 例如,如果今天是2006年6月1日,而conference_date是保留2006年6月29日的日期实例,则{{ conference_date | timeuntil }}将返回“4周”。
    使用可选参数,它是一个包含用作比较点的日期(而不是现在)的变量。 如果from_date包含2006年6月22日,则以下内容将返回“1周”:

{{ conference_date|timeuntil:from_date }}

 

四.标签Tags

for标签

遍历每一个元素

{% for person in person_list %}
        <p>{{ person.name }}</p>  <!--凡是变量都要用两个大括号括起来-->
{% endfor %}

 

反向循环

{% for obj in list reversed %}

 

遍历一个字典

{% for key,val in dic.items %}
    <p>{{ key }}:{{ val }}</p>
{% endfor %}

 

循环序号

​ 可以通过{{forloop}}显示,必须在循环内部用

forloop.counter            当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
forloop.counter0           当前循环的索引值(从0开始)
forloop.revcounter         当前循环的倒序索引值(从1开始)
forloop.revcounter0        当前循环的倒序索引值(从0开始)
forloop.first              当前循环是不是第一次循环(布尔值)
forloop.last               当前循环是不是最后一次循环(布尔值)
forloop.parentloop         本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等
with..as:
{% with 变量名=变量.属性.属性.. %}
{{ 变量 }}
{% endwith %}

或:

{% with 变量.属性.属性..  as 变量名%}

{% endwith %}

 

for..…empty

​ for标签带有一个可选的{% empty %}从句,如果给出的组是空的或没有找到时,可以行操作

{% for person in person_list %}
	<p>{{ person.name }}</p>
{% empty %}
 	<p>sorry,no person here</p>
{% endfor %}

​  

if标签

​ {% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。

{% if num > 100 or num < 0 %}
	<p>无效</p>  <!--不满足条件,不会生成这个标签-->
{% elif num > 80 and num < 100 %}
	<p>优良</p>
{% else %}  <!--也是在if标签结构里面的-->
	<p>及格</p>
{% endif %}

 也可以只有if和else

{% if user_list|length > 5 %}  <!--结合过滤器来使用-->
	长度大于5
{% else %}
	或者
{% endif %}

 

csrf_token

​ 以post提交表单的时候,会报错,之前在settings文件中把配置注释了,本身不应该被注释掉,这个标签用于跨站请求伪造保护.在页面的form表单内(一定要写在form表单里面)的任合位置加:

{% csrf_token %}

​ 这个用来对应验证是否是这个页面进行的提交

注释的写法:

{#...#}

 

其他:

  1. Django的模板语言不支持连续判断,即不支持以下写法:
  {% if a > b > c %}
  ...
  {% endif %}

 

  1. Django的模板语言中属性的优先级大于方法
  def xx(request):
   	d = {"a": 1, "b": 2, "c": 3, "items": "100"}
   	return render(request, "xx.html", {"data": d})

如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中:

  {{ data.items }}

默认会取d的items key的值。

 

五.模版继承

​ 可以创建一个基本的页面,还能定义被子模版覆盖的blocks,就是说有许多结构相同的页面,使用模版继承可以直接将母版的版式拿来使用,非常方便

 

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}My amazing site{%/span> endblock %}</title>
</head>
<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}
    </div>
    <div id="content">
    {% block content %}{% endblock %}
</div>
</body>
</html>

 

子模版代码:

{% extends "base.html" %}  # 这句话一定要写在第一行

{% block title %}子模版{% endblock %}

{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

 

为了方便可以给{%endblock%}标签一个名字,例如:

{%block content%}
...
{%endblock content%}

不能在一个模版中定义多个相同名字的block标签

 

六.组件

  可以将常用的页面内容,比如导航条,页头页尾这些组件保存在单独的文件中,然后再需要使用的地方,文件的任意位置按语法导入

{% include 'navbar.html' %}

 

组件.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .c1{
            background-color: red;
            height: 40px;
        }
    </style>
</head>
<body>
<div class="c1">
    <div>
        <a href="">xx</a>
        <a href="">dd</a>
    </div>
</div>
</body>
</html>

 

嵌入的页面.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% include 'nav.html' %}
<h1>xxxxxxxxxx</h1>
</body>
</html>
posted @ 2019-02-25 22:02  robertx  阅读(351)  评论(0编辑  收藏  举报