第1章 常用语法
两种特殊符号:
{{ }}:变量相关 {% %}:逻辑相关
1.1 变量
在Django的模板语言中使用{{ 变量名 }}定义变量。
变量的命名包括任何字母数字以及下划线 ("_")的组合,变量名称中不能有空格或标点符号。点(".")在模板语言中有特殊的含义,当模版系统遇到点(".")将以下面的顺序查询:
- 字典查询(Dictionary lookup)
- 属性或方法查询(Attribute or method lookup)
- 数字索引查询(Numeric index lookup)
注意:如果计算结果的值是可调用的,结果将被无参数的调用,调用的结果将成为模版的值;如果使用的变量不存在,模版系统将插入 string_if_invalid 选项的值,它被默认设置为空字符串。
【示例】:view.py中代码:
from django.shortcuts import HttpResponse, render, redirect def template_test(request): file_size = 123456789 name_list = ['张三', '李四', '王五'] name_list2 = [['张三0', '李四0', '王五0'], ['张三1', '李四1', '王五1']] name_dict = {'name1': '张三', 'name2': '李四', 'name3': '王五'} from datetime import datetime, timedelta now = datetime.now() yesterday = datetime.now()-timedelta(days=1) print(now) print(yesterday) a_html = "<a href='https://www.baidu.com'>我是后端传过来的a标签</a>" script_html = "<script>alert('test')</script>" c_str = """ 床前明月光 疑是地上霜 举头望明月 低头思故乡 """ w_ptr = """ Bright moonlight shines over my bed, Just like frost covering the land, Raise my head to look at the Moon, Miss my hometown when I look down. """ return render( request, 'template_test.html', { "file_size": file_size, 'name_list': name_list, 'name_list2':name_list2, 'name_dict': name_dict, 'now': now, 'yesterday': yesterday, 'a_html': a_html, 'script_html': script_html, 'c_str': c_str, 'w_str': w_ptr } )
模板中支持的写法:
{# 取l中的第一个参数 #} {{ l.0 }} {# 取字典中key的值 #} {{ d.name }} {# 取对象的name属性 #} {{ person_list.0.name }} {# .操作只能调用不带参数的方法 #} {{ person_list.0.dream }}
1.2 Filters(过滤器)
在Django的模板语言中通过使用过滤器来改变变量的显示。过滤器的语法:
{{ value|filter_name:参数 }}
使用管道符"|"来应用过滤器。例如:{{ name|lower }}会将name变量应用lower过滤器之后再显示它的值(lower在这里的作用是将文本全都变成小写)。过滤器具有如下特点:
- 过滤器支持“链式”操作,即一个过滤器的输出作为另一个过滤器的输入;
- 过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词;
- 过滤器参数包含空格的话必须用引号包裹起来,比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
注意:'|'左右不能存在空格
1.2.1 内置过滤器
1.2.1.1 default
如果一个变量是false或者为空则使用给定的默认值,否则使用变量的值:
{{ value|default:"nothing"}} # 如果value没有传值或者值为空的话就显示nothing
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>这是Django模板语言测试的html!</h1> <p>空值测试:{{ null_char|default:"这是一个空值" }}</p> </body> </html>
【运行结果】:
1.2.1.2 length
返回值的长度,作用于字符串和列表:
{{ value|length }} # 返回value的长度,如 value=['a','b','c','d']的话就显示4
【示例】:views.py
def template_test(request): name_list = ['张三', '李四', '王五'] name_dict = {'name1': '张三', 'name2': '李四', 'name3': '王五'} return render( request, 'template_test.html', { 'name_list': name_list, 'name_dict': name_dict } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>这是Django模板语言测试的html!</h1> <p>长度测试:{{ name_list|length }}</p> <p>长度测试:{{ name_dict|length }}</p> </body> </html>
【运行结果】:
1.2.1.3 filesizeformat
将值格式化为一个人类可读的文件尺寸:
{{ value|filesizeformat }} # 如果value是123456789,输出将会是 117.7 MB
【示例】:views.py
def template_test(request): file_size = 123456789 return render( request, 'template_test.html', { "file_size": file_size } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>这是Django模板语言测试的html!</h1> <p>文件大小:{{ file_size|filesizeformat }}</p> </body> </html>
【运行结果】:
1.2.1.4 slice
切片:
{{value|slice:"0:-1"}} # 从第首位到最后一位,不含最后一位
【示例】:views.py
def template_test(request): name_list = ['张三', '李四', '王五'] name_dict = {'name1': '张三', 'name2': '李四', 'name3': '王五'} return render( request, 'template_test.html', { 'name_list': name_list, 'name_dict': name_dict } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>这是Django模板语言测试的html!</h1> <p>切片:{{ name_list|slice:"0:-1" }}</p> <p>切片:{{ name_dict.name3|slice:"1:2" }}</p> </body> </html>
【运行结果】:
1.2.1.5 date
时间格式化:
{{ value|date:"Y-m-d H:i:s"}}
可用的参数:
格式化字符 | 描述 | 示例输出 |
a | 'a.m.'或'p.m.' | 'a.m.' |
A | 'AM'或'PM'。 | 'AM' |
b | 3个字母的文字月份,小写。 | 'jan'(一月) |
c | ISO 8601格式。 | 2008-01-02T10:30:00.000123+02:00
或2008-01-02T10:30:00.000123 |
d | 有前导零的月份的日子。 | '01'到'31' |
D | 文字星期,3个字符 | “星期五” |
e | 时区名称可能是任何格式,也可能返回一个空字符串,具体取决于datetime。 | ''、'GMT'、'-500'、'US/Eastern'等 |
f | 12小时制时间,如果分钟为0则不显示。 | '1','1:30' |
F | 文字显示的月份。 | '一月' |
g | 12小时格式小时,无前导零。 | '1'到'12' |
G | 24小时制小时,无前导零。 | '0'到'23' |
h | 12小时制小时,有前导零。 | '01'到'12' |
H | 24小时制小时,有前导零。 | '00'到'23' |
i | 分钟。 | '00'到'59' |
I | 夏令时间,无论是否生效。 | '1'或'0' |
j | 没有前导零的月份的日子。 | '1'到'31' |
l | 星期几。 | '星期五' |
L | 否是一个闰年(布尔值)。 | True或False |
m | 2位数字带前导零的月份。 | '01'到'12' |
M | 月,文字,3个字母。 | “扬” |
n | 没有前导零的月份。 | '1'到'12' |
N | 美联社风格的月份缩写。 | 'Jan.','Feb.','March','May' |
o | ISO-8601周编号,对应于使用闰年的ISO-8601周数(W)。 | '1999年' |
O | 与格林威治时间的差异在几小时内。 | '+0200' |
P | 12小时制时间和'a.m'/'p.m',分钟为零不显示,特殊情况 “午夜”和“中午”。 | '1 am','1:30 pm' / t3>,'midnight','noon','12:30 pm' / T10> |
r | RFC 5322格式化日期。 | 'Thu, 21 Dec 2000 16:01:07 +0200' |
s | 带前导零的秒。 | '00'到'59' |
S | 2个字符的一个月的英文序数后缀。 | 'st','nd','rd'或'th' |
t | 给定月份的天数。 | 28 to 31 |
T | 本机的时区。 | 'EST','MDT' |
u | 微秒。 | 000000 to 999999 |
U | 自Unix Epoch以来的时间(1970年1月1日00:00:00 UTC)。 | |
w | 星期几,数字无前导零。 | '0'(星期日)至'6'(星期六) |
W | ISO-8601周数,周数从星期一开始。 | 1,53 |
y | 2位数字的年份。 | '99' |
Y | 4位数字带年的年份。 | '1999年' |
z | 一年中的日子 | 0到365 |
Z | 时区偏移量,单位为秒。UTC以西时区的偏移量为负数, UTC以东为正。 | -43200到43200 |
【示例】:views.py
def template_test(request): from datetime import datetime now = datetime.now() print(now) return render( request, 'template_test.html', { 'now': now } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>这是Django模板语言测试的html!</h1> <p>时间格式化:{{ now|date:"Y-m-d H:i:s" }}</p> <p>时间格式化:{{ now|date:"a A P" }}</p> <p>时间格式化:{{ now|date:"c" }}</p> <p>时间格式化:{{ now|date:"b d D" }}</p> <p>时间格式化:{{ now|date:"Y-m-d f" }}</p> <p>时间格式化:{{ now|date:"I L" }}</p> <p>时间格式化:{{ now|date:"y-n-j G:i l T z" }}</p> </html>
【运行结果】:
1.2.1.6 safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,可以通过过滤器“|safe”的方式禁止Django对标签进行转义。
value = "<a href='#'>点我</a>" {{ value|safe}}
【示例】:views.py
def template_test(request): a_html = "<a href='https://www.baidu.com'>我是后端传过来的a标签</a>" script_html = "<script>alert('test')</script>" return render( request, 'template_test.html', { 'a_html': a_html, 'script_html': script_html } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>这是Django模板语言测试的html!</h1> <p>a标签:{{ a_html }}</p> <p>a标签:{{ a_html|safe }}</p> <p>js标签:{{ script_html }}</p> <p>js标签:</p> {{ script_html|safe }} </html>
【运行结果】:
1.2.1.7 truncatechars
如果字符串字符多于指定的字符数量则会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数:截断的字符数
{{ value|truncatechars:20}} # 以字符分隔
1.2.1.8 truncatewords
在一定数量的字后截断字符串。
{{ value|truncatewords:20}} # 以空格分隔作为一个words
【示例】:views.py
def template_test(request): c_str = """ 床前明月光 疑是地上霜 举头望明月 低头思故乡 """ w_ptr = """ Bright moonlight shines over my bed, Just like frost covering the land, Raise my head to look at the Moon, Miss my hometown when I look down. """ return render( request, 'template_test.html', { 'c_str': c_str, 'w_str': w_ptr } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <p>大段文本截断:{{ c_str|truncatechars:20 }}</p> <p>大段文本截断:{{ w_str|truncatewords:20 }}</p> </html>
【运行结果】:
1.2.1.9 cut
移除value中所有的与给出的变量相同的字符串:
{{ value|cut:' ' }} # 如果value为'i love you',那么将输出'iloveyou'
1.2.1.10 join
使用字符串连接列表:例如Python的str.join(list)
【示例】:views.py
def template_test(request): c_str = """ 床前明月光 疑是地上霜 举头望明月 低头思故乡 """ w_ptr = """ Bright moonlight shines over my bed, Just like frost covering the land, Raise my head to look at the Moon, Miss my hometown when I look down. """ return render( request, 'template_test.html', { 'c_str': c_str, 'w_str': w_ptr } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <p>cut测试:{{ w_str|cut:' ' }}</p> <p>join测试:{{ c_str|join:"," }}</p> </html>
【运行结果】:
1.2.1.11 timesince
将日期格式设为自该日期起的时间(例如,“4天,6小时”)。
采用一个可选参数,它是一个包含用作比较点的日期的变量(不带参数,比较点为现在)。例如:如果blog_date是表示2006年6月1日午夜的日期实例,并且comment_date是2006年6月1日08:00的日期实例,则以下将返回“8小时”:
{{ blog_date|timesince:comment_date }}
分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回“0分钟”。
1.2.1.12 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 }}
【示例】:views.py
def template_test(request): from datetime import datetime, timedelta now = datetime.now() yesterday = datetime.now()-timedelta(days=1) print(now) print(yesterday) return render( request, 'template_test.html', { 'now': now, 'yesterday': yesterday } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <p>timesince测试:{{ yesterday|timesince:now }}</p> <p>timeuntil测试:{{ now|timeuntil:yesterday }}</p> </html>
【运行结果】:
1.2.2 自定义filter
自定义过滤器只是带有一个或两个参数的Python函数:
- 变量(输入)的值:不一定是一个字符串
- 参数的值:这可以有一个默认值,或完全省略
例如,在过滤器{{var | foo:'bar'}}中,过滤器foo将传递变量var和参数“bar”。
1.2.2.1 自定义filter代码文件摆放位置
app01/ templatetags/ # 在app01下面新建一个package package myfilter.py # 建一个存放自定义filter的文件

1.2.2.2 编写自定义filter
from django import template # 生成一个注册用的实例 register = template.Library() # 定义并注册一个自定义的filter函数 @register.filter(name="ac") def add_char(arg): return "{} handsome.".format(arg) # 告诉Django的模板语言现在有一个自定义的filter方法,名字叫as @register.filter(name="as") def add_str(arg1,arg2): """ 第一个参数永远是管道符前面那个变量 :param arg1: 管道符前面那个变量 :param arg2: 冒号后面的变量 :return: """ return "{} {}.".format(arg1,arg2)
1.2.2.3 使用自定义filter
{# 先导入自定义filter文件 #} {% load myfilter %} {# 使用自定义的filter #} <p>自定义过滤器测试:{{ name_list|ac }}</p> <p>自定义过滤器测试:{{ name_dict.name2|as:"handsome" }}</p>
【示例】:views.py
def template_test(request): name_list = ['张三', '李四', '王五'] name_dict = {'name1': '张三', 'name2': '李四', 'name3': '王五'} return render( request, 'template_test.html', { 'name_list': name_list, 'name_dict': name_dict } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> {% load myfilter %} <p>自定义过滤器测试:{{ name_list|ac }}</p> <p>自定义过滤器测试:{{ name_dict.name2|as:"handsome" }}</p> </html>
【运行结果】:
1.3 Tags
1.3.1 for循环
1.3.1.1 普通for循环
<ul> {% for user in user_list %} <li>{{ user.name }}</li> {% endfor %} </ul>
for循环可用的一些参数:
Variable | Description |
forloop.counter | 当前循环的索引值(从1开始) |
forloop.counter0 | 当前循环的索引值(从0开始) |
forloop.revcounter | 当前循环的倒序索引值(从1开始) |
forloop.revcounter0 | 当前循环的倒序索引值(从0开始) |
forloop.first | 当前循环是不是第一次循环(布尔值) |
forloop.last | 当前循环是不是最后一次循环(布尔值) |
forloop.parentloop | 本层循环的外层循环 |
【示例】:views.py
def template_test(request): name_list = ['张三', '李四', '王五'] name_list2 = [['张三0', '李四0', '王五0'], ['张三1', '李四1', '王五1']] name_dict = {'name1': '张三', 'name2': '李四', 'name3': '王五'} return render( request, 'template_test.html', { 'name_list': name_list, 'name_dict': name_dict } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <p>for单次循环测试</p> <ul> {% for name in name_list %} {% if forloop.last %} <li class="dsb">{{ forloop.revcounter }}-{{ name }}</li> {% else %} <li class="{% if forloop.first %}'handsome'{% endif %}">{{ forloop.revcounter }}-{{ name }}</li> {% endif %} {% endfor %} </ul> <p>for双层循环测试</p> {% for name_outer in name_list2 %} {% for name_inner in name_outer %} <li> {{ forloop.parentloop.counter }} {{ forloop.counter }} {{ name_inner }} </li> {% endfor %} {% endfor %} </html>
【运行结果】:
1.3.1.2 for ... empty
<ul> {% for user in user_list %} <li>{{ user.name }}</li> {% empty %} <li>暂时还没有数据哦!</li> {% endfor %} </ul>
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <ul> {% for user in user_list %} <li>{{ user.name }}</li> {% empty %} <li>暂时还没有数据哦!</li> {% endfor %} </ul> </html>
【运行结果】:
1.3.2 if判断
1.3.2.1 if,elif和else
{% if user_list %} 用户人数:{{ user_list|length }} {% elif black_list %} 黑名单数:{{ black_list|length }} {% else %} 没有用户 {% endif %}
1.3.2.2 if和else
{% if user_list|length > 5 %} 七座豪华SUV {% else %} 黄包车 {% endif %}
提示|:if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
【示例】:views.py
def template_test(request): name_list = ['张三', '李四', '王五'] name_list2 = [['张三0', '李四0', '王五0'], ['张三1', '李四1', '王五1']] name_dict = {'name1': '张三', 'name2': '李四', 'name3': '王五'} return render( request, 'template_test.html', { 'name_list': name_list, 'name_dict': name_dict } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <p>===============if...elif...else测试==================</p> {% if p3 %} <p>p3:{{ p3 }}</p> {% elif p2 %} <p>p2:{{ p2 }}</p> {% else %} <p>什么人都没有!</p> {% endif %} <p>===============if...else测试=====================</p> {% if name_list|length >= 3 %} <p>需要打两辆车</p> {% else %} <p>需要打一辆车</p> {% endif %} </body> </html>
【运行结果】:
1.3.3 with别名
定义一个中间变量,多用于给一个复杂的变量起别名。注意等号左右不要加空格。
{% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %}
或
{% with business.employees.count as total %} {{ total }} employee{{ total|pluralize }} {% endwith %}
【示例】:views.py
def template_test(request): name_list = ['张三', '李四', '王五'] name_list2 = [['张三0', '李四0', '王五0'], ['张三1', '李四1', '王五1']] name_dict = {'name1': '张三', 'name2': '李四', 'name3': '王五'} return render( request, 'template_test.html', { 'name_list': name_list, 'name_dict': name_dict } )
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <p>with语句测试</p> {{ name_list2.1.1 }} <hr> {% with name=name_list2.1.1 %} {{ name }} {% endwith %} </body> </html>
【运行结果】:
1.3.4 csrf_token安全防护
这个标签用于跨站请求伪造保护。在页面的form表单里面写上{% csrf_token %}
1.3.5 注释
{# ... #}
1.3.6 注意事项
- Django的模板语言不支持连续判断,即不支持以下写法:
{% if a > b > c %} ... {% endif %}
- 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的值。
1.4 母板
1.4.1 为什么要有模板和继承
html页面有重复的代码,把它们提取出来放到一个单独的html文件,其他的页面只需要继承母版就可以了,可以减少代码冗余。
1.4.2 使用的步骤
- 把公用的HTML部分提取出来,放到html文件中;
- 在html中,通过定义block,把每个页面不同的部分区分出来;
- 在具体的页面中,先继承母版;
- 然后block名去指定替换母版中相应的位置;
1.4.3 使用母版和继承的注意事项
- {% extends 'base.html' %}中母版文件html要加引号
- {% extends 'base.html' %}必须放在子页面的第一行
- 可以在html中定义很多block,通常我们会额外定义page-css和page-js两个块
- py相应的函数中返回的是对应的子页面文件而不是 base.html
- 提示:我们通常会在母板中定义页面专用的CSS块和JS块,方便子页面替换。
1.4.4 模板格式示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>母版模板</title> {% block page-css %} {# CSS块 #} {% endblock %} </head> <body> <h1>这是母板的标题</h1> {% block page-main %} {# 主要内容块 #} {% endblock %} <h1>母板底部内容</h1> {% block page-js %} {# JS块 #} {% endblock %} </body> </html>
1.4.5 继承母板
在子页面中在页面最上方使用下面的语法来继承母板:
{% extends 'base.html' %}
1.4.6 块(block)
通过在母板中使用{% block xxx %}来定义"块";
在子页面中通过定义母板中的block名来对应替换母板中相应的内容:
{% block page-main %} <p>世情薄</p> <p>人情恶</p> <p>雨送黄昏花易落</p> {% endblock %}
1.4.7 组件
可以将重复的代码包装成一个独立的小html文件,这个小html文件叫做组件。可以将常用的页面内容如导航条、页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入:
{% include 'navbar.html' %}
1.4.8 模板使用示例
【示例】:母版页面:base.html
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="https://v3.bootcss.com/favicon.ico"> <title>BMS-图书管理系统</title> <!-- Bootstrap core CSS --> {% load static %} <link href="{% static 'bootstrap/css/bootstrap.min.css'%}" rel="stylesheet"> <!-- Custom styles for this template --> <link href="{% static 'dashboard.css'%}" rel="stylesheet"> <link rel="stylesheet" href="{% static 'fontawesome/css/font-awesome.min.css'%}"> {% block page-css %} {% endblock %} </head> <body> {% include 'navbar.html' %} <div class="container-fluid"> <div class="row"> <div class="col-sm-3 col-md-2 sidebar"> <ul class="nav nav-sidebar"> <li class="{% block publisher_class %}{% endblock %}"><a href="/publisher_list/">出版社列表页</a></li> <li class="{% block book_class %}{% endblock %}"><a href="/book_list/">书籍列表</a></li> <li class="{% block author_class %}{% endblock %}"><a href="/author_list/">作者列表</a></li> </ul> </div> <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> {# 这里是每个页面不同的部分 #} {% block page-main %} {% endblock %} </div> </div> </div> <div class="modal fade" tabindex="-1" role="dialog" id="myModal"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span> </button> <h4 class="modal-title">用户信息</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">邮箱</label> <div class="col-sm-10"> <input type="email" class="form-control" id="inputEmail3" placeholder="Email"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">密码</label> <div class="col-sm-10"> <input type="password" class="form-control" id="inputPassword3" placeholder="Password"> </div> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">取消</button> <button type="button" class="btn btn-primary">保存</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal --> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script src="{% static 'jquery-3.3.1.js'%}"></script> <script src="{% static 'bootstrap/js/bootstrap.min.js'%}"></script> {% block page-js %} {% endblock %} </body> </html>
【示例】:导航栏组件:navbar.html
<nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="https://v3.bootcss.com/examples/dashboard/#">BMS-S10</a> </div> <div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav navbar-right"> <li><a href="https://v3.bootcss.com/examples/dashboard/#">Dashboard</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/#">Settings</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/#">Profile</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/#">Help</a></li> </ul> <form class="navbar-form navbar-right"> <input type="text" class="form-control" placeholder="Search..."> </form> </div> </div> </nav>
【示例】:出版社列表页面:publisher_list.html
{% extends 'base.html' %} {% block page-main %} <h1 class="page-header">出版社管理页面</h1> <div class="panel panel-primary"> <!-- Default panel contents --> <div class="panel-heading">出版社列表 <i class="fa fa-thumb-tack pull-right"></i></div> <div class="panel-body"> <div class="row" style="margin-bottom: 15px"> <div class="col-md-4"> <div class="input-group"> <input type="text" class="form-control" placeholder="Search for..."> <span class="input-group-btn"> <button class="btn btn-default" type="button">搜索</button> </span> </div><!-- /input-group --> </div><!-- /.col-md-4 --> <div class="col-md-1 pull-right"> <button class="btn btn-success" data-toggle="modal" data-target="#myModal">新增</button> </div> </div><!-- /.row --> <table class="table table-bordered"> <thead> <tr> <th>#</th> <th>id</th> <th>出版社名称</th> <th>操作</th> </tr> </thead> <tbody> {% for publisher in publisher_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ publisher.id }}</td> <td>{{ publisher.name }}</td> <td> <a class="btn btn-danger" href="/delete_publisher/ id={{ publisher.id }}">删除</a> <a class="btn btn-info" href="/edit_publisher/ id={{ publisher.id }}">编辑</a> </td> </tr> {% endfor %} </tbody> </table> <nav aria-label="Page navigation" class="text-right"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> </div> </div> {% endblock %} {% block publisher_class %} active {% endblock %}
【示例】:书籍列表页面:book_list.html
{# 继承母版 #} {% extends 'base.html' %} {# 把自己页面的内容 塞到母版里面相应的位置 #} {% block page-main %} <h1 class="page-header">书籍管理页面</h1> <div class="panel panel-primary"> <!-- Default panel contents --> <div class="panel-heading">书籍列表 <i class="fa fa-thumb-tack pull-right"></i></div> <div class="panel-body"> <div class="row" style="margin-bottom: 15px"> <div class="col-md-4"> <div class="input-group"> <input type="text" class="form-control" placeholder="Search for..."> <span class="input-group-btn"> <button class="btn btn-default" type="button">搜索</button> </span> </div><!-- /input-group --> </div><!-- /.col-md-4 --> <div class="col-md-3 pull-right"> <a href="/add_book/" class="btn btn-success pull-right">新页面添加</a> <button class="btn btn-success pull-right" data-toggle="modal" data-target="#myModal">新增</button> </div> </div><!-- /.row --> <table class="table table-bordered"> <thead> <tr> <th>#</th> <th>id</th> <th>书名</th> <th>出版社名称</th> <th>操作</th> </tr> </thead> <tbody> {% for i in all_book %} <tr> <td>{{ forloop.counter }}</td> <td>{{ i.id }}</td> <td>{{ i.title }}</td> <td>{{ i.publisher.name }}</td> <td> <a class="btn btn-danger" href="/delete_book/ id={{ i.id }}">删除</a> <a class="btn btn-info" href="/edit_book/ id={{ i.id }}">编辑</a> </td> </tr> {% empty %} <tr> <td colspan="5" class="text-center">暂时没有数据哦~</td> </tr> {% endfor %} </tbody> </table> <nav aria-label="Page navigation" class="text-right"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> </div> </div> {% endblock %} {% block book_class %} active {% endblock %} {% block page-css %} {% load static %} {# <link rel="stylesheet" href="{% static 'book_list_only.css' %}">#} <link rel="stylesheet" href="{% get_static_prefix %}book_list_only.css"> {% endblock %}
【示例】:作者列表页面:author_list.html
{% extends 'base.html' %} {% block page-main %} <h1 class="page-header">作者管理页面</h1> <!-- 面板开始 --> <div class="panel panel-primary"> <!-- Default panel contents --> <div class="panel-heading">作者列表 <i class="fa fa-thumb-tack pull-right"></i></div> <div class="panel-body"> <div class="row" style="margin-bottom: 15px"> <div class="col-md-4"> <div class="input-group"> <input type="text" class="form-control" placeholder="Search for..."> <span class="input-group-btn"> <button class="btn btn-default" type="button">搜索</button> </span> </div><!-- /input-group --> </div><!-- /.col-md-4 --> <div class="col-md-3 pull-right"> <a href="/add_author/" class="btn btn-success pull-right"><i class="fa fa-plus fa-fw"></i>新页面添加</a> <button class="btn btn-success pull-right" data-toggle="modal" data-target="#myModal">新增 </button> </div> </div><!-- /.row --> <table class="table table-bordered"> <thead> <tr> <th>#</th> <th>id</th> <th>作者名字</th> <th>作品</th> <th>操作</th> </tr> </thead> <tbody> {% for author in author_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ author.id }}</td> <td>{{ author.name }}</td> <td> {% for book in author.book.all %} {{ book.title }} {% endfor %} </td> <td> <a class="btn btn-danger" href="/delete_author/ id={{ author.id }}"><i class="fa fa-trash-o fa-fw"></i>删除</a> <a class="btn btn-info" href="/edit_author/ id={{ author.id }}"><i class="fa fa-pencil fa-fw"></i>编辑</a> </td> </tr> {% endfor %} </tbody> </table> <nav aria-label="Page navigation" class="text-right"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> </div> </div> {% endblock %} {% block author_class %} active {% endblock %} {% block page-js %} <script src="/static/author_list_only.js"></script> {% endblock %}
1.5 静态文件相关
1.5.1 {% static %}
利用Django模板语言内置的static方法拼接静态文件的路径:
{% load static %} <link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
引用JS文件时使用:
{% load static %} <script src="{% static "mytest.js" %}"></script>
某个文件多处被用到可以存为一个变量:
{% load static %} {% static "images/hi.jpg" as myphoto %} <img src="{{ myphoto }}"></img>
1.5.2 {% get_static_prefix %}
利用内置的get_static_prefix获取静态文件路径的别名自行拼接路径:
{% load static %} <link href="{% get_static_prefix %}bootstrap/css/bootstrap.min.css" rel=stylesheet>
或者
{% load static %} # 一个路径如果多次用到可以使用as保存到一个变量,后面直接使用变量代替具体路径 {% get_static_prefix as STATIC_PREFIX %} <img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" /> <img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />
1.6 自定义tag
1.6.1 simple_tag
和自定义filter类似,只不过接收更灵活的参数(参数个数大于2个)。
- 定义注册simple tag:
@register.simple_tag(name="plus") def plus(a, b, c): return "{} + {} + {}".format(a, b, c)
- 使用自定义simple tag:
{% load mytag %} {# simple tag #} {% plus "1" "2" "abc" %}
1.6.2 inclusion_tag
多用于返回html代码片段。
【示例】:mytag.py
from django import template # 生成注册示例,名字必须是register register = template.Library() @register.simple_tag(name="plus") def plus(a, b, c): return "{} + {} + {}".format(a, b, c) @register.inclusion_tag('result.html') def show_results(n): n = 1 if n < 1 else int(n) data = ["第{}项".format(i) for i in range(1, n+1)] return {"data": data}
【示例】:urls.py
urlpatterns = [ url(r'^template_test/', views.template_test) ]
【示例】:result.html
<ul> {% for choice in data %} <li>{{ choice }}</li> {% endfor %} </ul>
【示例】:template_test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template_test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> {% load mytag %} {% show_results 10 %} {% plus "1" "2" "abc" %} </html>
【运行结果】:
第2章 参考资料
http://www.cnblogs.com/liwenzhou/p/7931828.html
https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#std:templatetag-for
