目录
模板渲染系统
1. 语法
可做动态页面----字符串替换。
{{ 变量 }} ---变量相关 {% 逻辑 %} ---逻辑相关
2. 变量 {{ 变量名 }}
当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。
变量的命名包括任何字母数字以及下划线 ("_")的组合。 变量名称中不能有空格或标点符号。
万能的点("."):可以取字符串,字典,列表的索引位置,类对象的属性、方法(不能传参)...
当模版系统遇到点("."),它将以这样的顺序查询:
字典查询(Dictionary lookup)
属性或方法查询(Attribute or method lookup)
数字索引查询(Numeric index lookup)
urls.py
def test(request): name = '24期' lst = ['aa', 'bb', 'cc', 'dd'] dic = {'k1':'v1', 'k2':'v2'} num = 110 class Person(object): p = '人类' def dream(self): return 'dreamer' obj = Person() # 方式一: return render(request, 'test.html', {'name':name,'lst':lst,'dic':dic,'obj':obj}) # 传参数(字典形式) 模板渲染,在回复浏览器之前做的事情 # 方式二: return render(request, 'test.html', locals()) #locals()获取函数内所有的变量,共同通过render方法交给test.html文件进行模板渲染,效率较低
test.html文件:
调用对象里面的方法的时候,不需要写括号来执行,并且只能执行不需要传参数的方法,如果你的这个方法需要传参数,那么模板语言不支持、不渲染。
<body> <h1>{{name}}</h1> <h2>{{lst.1}}</h2> <!--取索引位置1的数据--> <h2>{{dic.键}}</h2> <!-- 获取值--> <h2>{{dic.keys}}</h2> <!--所有的键 dict_keys(['k1', 'k2'])--> <h2>{{dic.values}}</h2> <!--所有的值 dict_values(['v1', 'v2'])--> <h2>{{dic.items}}</h2> <!--dict_items([('k1', 'v1'), ('k2', 'v2')])--> <h2> {{ obj }} </h2> <!-- <app01.views.test.<locals>.Person object at 0x000002177B42EE80> --> <h2> {{ obj.p }} </h2> <!-- 取类属性属性值 --> <h2> {{ obj.dream }} </h2> <!--调用类的方法,不能传参--> </body>
3. 过滤器(内置)
在Django的模板语言中,通过使用 过滤器 来改变变量的显示。
语法:
{{ value|过滤器:参数 }}
注意事项:
- 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
- 过滤器可以接受参数, 冒号: 后面接参数。
- 过滤器参数包含空格的话,必须用引号包裹起来。比如join过滤器。
- “|”左右两边不能有空格
default
如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值,无法找到。
{{ value|default:"nothing" }} # 如果value没有传值或者值为空的话就显示nothing
length
返回值的长度,作用于字符串和列表。
{{ value|length }} # 长度
filesizeformat
将书值格式化为一个 “人类可读的” 文件尺寸(13kb,4MB)
{{ value|filesizeformat }} # 如果 value 是 123456789,输出将会是 117.7 MB。
slice
切片,除了字符串,还有其他可切片的数据类型
{{ value|slice:"1:3" }}
date
格式化,如果 value=datetime.datetime.now()
{{ value|date:"Y-m-d H:i:s" }}
safe
将字符串的标签识别成标签。
value = "<a href='#'>点我</a>"
{{ value|safe }}
truncatechars
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数:截断的字符数
{{ value|truncatechars:9 }} #注意:最后那三个省略号也是9个字符里面的,也就是这个9截断出来的是6个字符+3个省略号,那怎么展开啊,配合前端的点击事件就行啦
truncatewords
在一定数量的字后截断字符串,是截多少个单词。(按空格取)
例如:‘hello girl hi baby yue ma’,
{{ value|truncatewords:3}} #上面例子得到的结果是 'hello girl h1...'
cut
移除value中所有的与给出的变量相同的字符串
{{ value|cut:' ' }} # 移除空格 如果value为'i love you',那么将输出'iloveyou'.
join
使用字符串连接列表中的数据。
{{ list|join:'_' }} # 像Python的str.join(list)
timesince
将日期格式设为自该日期起的时间(例如,“4天,6小时”)。
采用一个可选参数,它是一个包含用作比较点的日期的变量(不带参数,比较点为现在)。 例如,如果blog_date是表示2019年6月1日午夜的日期实例,并且comment_date是2019年6月1日08:00的日期实例,则以下将返回“8小时”:
{{ blog_date|timesince:comment_date }}
timeuntil
似于timesince,除了它测量从现在开始直到给定日期或日期时间的时间。
还能够计算周数。 例如,如果今天是2019年6月1日,而conference_date是2019年6月29日的日期实例,则{{ conference_date | timeuntil }}将返回“4周”。
使用可选参数,它是一个包含用作比较点的日期(而不是现在)的变量。 如果from_date包含2019年6月22日,则以下内容将返回“1周”:
{{ conference_date|timeuntil:from_date }}
示例:
views.py 文件
def test(request): import datetime date = datetime.datetime.now() blog_date = datetime.datetime(2019,9,25,00,00,00) comment_date = datetime.datetime(2019,9,26,18,00,00) conference_date = datetime.datetime(2019,9,1,00,00,00) from_date = datetime.datetime(2019,9,30,00,00,00) file_size = 123456789 a = "<a href='http://www.baidu.com' target='_blank'>百度</a>" english = 'I love you my lover!' lst = ['aa', 'bb', 'cc', 'dd'] flag = False return render(request, 'test.html', locals())
test.html文件:
<body> <p>{{ flag|default:'这是空!' }}</p> {# 这是空! #} <p>{{ lst|length }}</p> {# 4 #} <p>{{ file_size|filesizeformat }}</p> {# 117.7MB #} <p>{{ english|slice:"0:2" }}</p> {# I #} <p>{{ date|date:"Y-m-d H:i:s" }}</p> {# 2019-09-25 18:13:14 #} <p>{{ a|safe }}</p> {# 百度 能够识别a标签 #} <p>{{ english|upper }}</p> {# 全部大写 #} <p>{{ english|truncatechars:9 }}</p> {# I love... #} <p>{{ english|truncatewords:3 }}</p> {# I love you ... #} <p>{{ english|cut:' ' }}</p> {# Iloveyoumylover! #} <p>{{ lst|join:'_' }}</p> {# aa_bb_cc_dd #} <p>{{ blog_date|timesince:comment_date }}</p> {# 1 day, 18 hours #} <p>{{ conference_date|timesince:from_date }}</p> {# 4 weeks #} <p>{{ date|timesince:from_date }}</p> {# 3 days, 17 hours #} </body>
4. 标签 -- {% tag %}逻辑
{% tag %} {% endtag %}
for标签
遍历每一个元素: 写个for,然后 tab键自动生成for循环的结构,循环很基础,就这么简单的用,没有什么break之类的,复杂一些的功能,你要通过js
<ul> {% for i in list %} <li> {{i}} </li> {% endfor %} </ul> # {% for i in list reversed %}反向完成循环
循环序号可以通过{{forloop}}显示,必须在循环内部用
forloop.counter 当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能 forloop.counter0 当前循环的索引值(从0开始) forloop.revcounter 当前循环的倒序索引值(从1开始) forloop.revcounter0 当前循环的倒序索引值(从0开始) forloop.first 当前循环是不是第一次循环(布尔值) forloop.last 当前循环是不是最后一次循环(布尔值) forloop.parentloop 本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等
示例:
lst = ['你好','Hello','世界', 'word']
<body> <ul> {% for i in lst %} <li>{{ forloop.counter }}---{{ i }} </li> {% endfor %}</ul></body> 结果: 1---你好 2---Hello 3---世界 4---word
嵌套:
dic = {'k1':'v1', 'k2':'v2', 'k3':[1,2,3,4,5]}
<ul> {% for i in dic %} {% for k,v in dic.items %} <li>{{ forloop.counter }}--{{ forloop.parentloop.counter }} === {{ k }} -- {{ v }}</li> {% endfor %} {% endfor %} </ul> 结果: 1--1 === k1 -- v1 2--1 === k2 -- v2 3--1 === k3 -- [1, 2, 3, 4, 5] 1--2 === k1 -- v1 2--2 === k2 -- v2 3--2 === k3 -- [1, 2, 3, 4, 5] 1--3 === k1 -- v1 2--3 === k2 -- v2 3--3 === k3 -- [1, 2, 3, 4, 5]
for ... empty
for
标签带有一个可选的{% empty %}
从句,以便在给出的组是空的或者没有被找到时,可以有所操作。
{% for person in person_list %} <p>{{ person }}</p> {% empty %} <p>没有找到东西!</p> {% endfor %}
if 标签
{% if %}
会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断,注意条件两边都有空格。
{% if num > 100 or num < 0 %} <p>成绩无效!</p> {% elif num > 80 and num <= 100 %} <p>成绩优秀</p> {% else %} <p>一般般</p> {% endif %}
结合过滤器使用
{% if user_list|length > 5 %} <!--结合过滤器来使用--> <p>七座豪华SUV</p> {% else %} <p>黄包车</p> {% endif %}
with 标签
使用一个简单地名字缓存一个复杂的变量,多用于给一个复杂的变量起别名。
with: 等号两边不能有空格
{% with total=business.employees.count %} {{ total }} <!--只能在with语句体内用--> {% endwith %}
with...as... 效果一样
{% with business.employees.count as total %} {{ total }} {% endwith %}
示例:
dic = {'k1':'v1', 'k2':'v2', 'k3':[1,2,3,4,5]}
{% with d=dic.k3.2 %} {{ d }} {% endwith %} {% with dic.k3.3 as d1 %} {{ d1 }} {% endwith %}
5. 模板继承
继承
extends
标签是关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先,它将定位父模版。
然后通过block
标签中的名字,将父模板对应的block标签替换。
不能在一个模版中定义多个相同名字的 block
标签。
{% extends 'muban.html'} # 继承muban.html页面,必须写 # 预留钩子,供其他需要继承它的html页面,能够自己自定义某些内容 # content是名字,便于子页面对应替换,子页面也要写对应钩子(开块替换内容)。 {% block content %} ... {% endblock content %} {% block css %} {{ block.super }} # 将子页面的内容和继承的母版中block里面的内容同时保留 {% endblock css %} {% block js %} ... {% endblock js %}
组件
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方,文件的任意位置按如下语法导入即可。
{% include '组件文件' %} 例: {% include 'navbar.html' %} # 引用组件
组件和插件的简单区别:
组件是提供某一完整功能的模块,如:编辑器组件,QQ空间提供的关注组件 等。 而插件更倾向封闭某一功能方法的函数。 这两者的区别在 Javascript 里区别很小,组件这个名词用得不多,一般统称插件。
自定义标签和过滤器
自定义过滤器
- app应用文件夹中创建一个templatetags文件夹,必须是这个名字
- 在templatetags文件夹中创建一个自定义py文件,如mytag.py
- 在py文件中创建自定义过滤器
- html文件中使用
- 注意:参数最多两个
自定义mytag.py文件
from django import template register = templatr.Library() # 固定的名字register @register.filter def my_filter(v1,v2): # v1接收管道符'|'前的参数 """ 有参数的过滤器,最多两个参数 :param v1: 接收管道符前的参数 :param v2: 接收过滤器冒号后的参数 :return:v1+v2 """ return v1+v2 # 两个字符串拼接
tag.html文件:
{% load 文件 %} # 加载py文件 {% load mytag %} {{ name|my_filte:参数 }} # 接收views视图函数的参数(替换) 示例: {% load mytag %} <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <h1> {{ name|my_filter:'sb' }} </h1> </body> </html>
views视图函数
def tag(request): name = 'alex' return render(request, 'tag.html', {'name': name})
自定义标签
- app应用文件夹中创建一个templatetags文件夹,必须是这个名字
- 在templatetags文件夹中创建一个自定义py文件
- 创建自定义标签
- html文件中使用
- 注意:参数可传多个
mytag.py文件
from django import template register = templatr.Library() # 固定的名字register @register.simple_tag def my_tag(v1, v2): return v1+v2 # 字符串拼接
tag.html文件
{% load mytag %} # 加载 mytag.py文件,放在最上面 {% my_tag name '帅比' %} # 标签 参数1 参数2 参数3...
views视图函数
def tag(request): name = 'alex' return render(request, 'tag.html', {'name': name})
inclusion_tag标签
多用于返回html代码片段。
- 创建一个result.html文件,
<body> <ul> {% for i in lst %} <li>{{ i }}</li> {% endfor %} </ul> </body>
- views视图:
def inclusion_tag(request): lst = [11, 22, 33, 44, 55] return render(request, 'inc_tag.html', {'lst': lst})
- 在mytag.py文件中,写inclusion_tag标签
from django import template register = template.Library() @register.inclusion_tag('result.html') # 将result.html里面的内容用下面函数的返回值渲染,然后作为一个组件一样,加载到使用这个函数的html文件里面 def in_tag(v1): # 接收in_tag.html文件中的lt参数 return {'lst': v1} # 将lst交与result.html文件渲染
- 创建in_tag.html文件
{% load mytag %} # 加载mytag.py文件 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> {% in_tag lt %} # 替换mytag.py中的in_tag函数,接收lst参数 </body> </html>
静态文件配置
首先在项目路径下创建一个文件夹,如:statics
在文件夹下创建css等文件夹,并创建静态文件,如:test.css
在settind中配置静态文件路径
在 STATIC_URL = '/static/' (静态文件路径别名)下面写:
STATICFILES_DIPS=[ os.path.join(BASE_DIR,'statics') ]
- 在html文件中引入css文件,也可以引入bootstrap框架
<link rel="stylesheet" href='/static/css/test.css'> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">