前言:前一章说到,路由与分路由app的大致构造,在这基础上将加入模板对各个app进行进一步加工。考虑到废话太多,本章起将偏重于实例使用。
模板配置
- 创建模板文件 templates,包含所有的app模板
- 创建一个测试用模板 book_index.html
├── book
├── db.sqlite3
├── manage.py
├── mydjango
└── templates
└── book
└── book_index.html
- 模板路径拼接 settings.py -> TEMPLATES
'DIRS': [os.path.join(BASE_DIR, 'templates')],
三种渲染方法
- 渲染的方式有以下三种,其中第一、二种在实例中并不常用。
- 硬编码,一般情况下硬编码的形式并不使用,在之前的章节中,用到了硬编码的形式去测试。
def index_mode1(request):
return HttpResponse('硬编码页面')
- 获取模板再加载
from django.template.loader import get_template
def index_mode2(request):
temp = get_template('book/book_index.html')
html = temp.render()
return HttpResponse(html)
- 使用 render 进行渲染()
from django.shortcuts import render
def index_mode(request):
return render(request, 'book/book_index.html')
模板变量
- 语法使用 {{ 变量名 }}
- 支持传递的类型 (字典、模型、方法、函数、列表、元组)
- 在 render 中使用 context 参数进行传递
class ClassTest(object):
def __init__(self, name):
self.name = name
def run(self):
return '我是类的run'
def test():
return "我是一个测试的函数"
list1 = ['a', 'b', 'c', 'd']
tu1 = ('a', 'b', 'c', 'd')
string1 = '我是一个测试的字符串'
dict1 = {
'key1': '我是测试用的字典value'
}
# 使用render 渲染]
def index_mode(request):
return render(request, 'book/book_index.html', context={
'classTest': ClassTest('一个名字'),
'test': test,
'list1': list1,
'tuple1': tu1,
'string1': string1,
'dict1': dict1
})
- 传递后出现的效果
过滤器
- 作用:对变量进行过滤。在真正渲染出来之前,过滤器会根据功能处理好变量,然后得出结果后再替换掉原来的变量展示出来
- 语法{{ 变量名|对应方法 }}
{{name|first}} # 取得字符串第一个字符
{{name|join:'*' # 拼接
{{name|slice:"1:3"}} # 切割
- 常用过滤器表
过滤器 | 用途 |
---|---|
add | 字符串、数字、列表相加。失败则返回空字符串 |
default | 提供一个默认值,原值被django认定为False时使用默认值 |
first | 返回可迭代对象第一个值 |
last | 返回可迭代对象最后一个值 |
date | 格式化日期和时间 |
time | 格式化时间 |
join | 拼接,同python的join用法 |
length | 返回字符串或是列表的长度 |
length_is | 字符串或者列表长度是否为指定的值 |
lower | 所有字符串变成小写 |
truncatechars | 根据给定的参数进行字符截断。超过则用…表示 |
truncatewords | 同上一个,此过滤器以单词为单位进行截断 |
capfirst | 首字母大写 |
slice | 切割可迭代对象,与python切片用法一致,区间为前闭合后开放 |
striptags | 去掉所有html标签 |
safe | 关闭变量的自动转义 |
floatformat | 浮点数格式化 |
- date 与 time 的过滤器格式
用例说明
# 传入一个时间对象 datetime.datetime.now
# 如不使用格式化参数,则使用默认格式
{{now|date:'Y/m/d H:i:s'}}
{{now|time:'h:i:s'}}
- date 和 time 格式化参数表
参数 | 说明 |
---|---|
Y | 四位数的年。如:1999 |
y | 两位数的年。如:99 |
m | 两位数的月。如:01,09,12 |
n | 一位数的月。如:1,9,12 |
d | 两位数的日。如:01,09,12 |
j | 一位数的日。如:1,9,12 |
g | 12小时制的一位数的小时。如:1,9,12 |
G | 24小时制的一位数的小时。如:0,8,23 |
h | 12小时制的两位数的小时。如:01,09,12 |
H | 24小时制的两位数的小时。如:01,13,24 |
i | 分钟。从00~59 |
s | 秒。从00~59 |
静态文件
- 主项目目录下创建 static 文件,根据需求分类创建子文件夹
├── static
├── css
│ └── test.css
├── img
│ └── panda.jpg
└── js
└── test.js
- 设置静态文件目录路径,同 templates 设置方法,settings.py -> STATICFILES_DIRS
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
- 静态文件的导入以及三种常见的文件导入示例
{% load static %} # 加载静态文件
# 常见的三种文件导入示例
<link rel="stylesheet" href="{% static 'css/test.css' %}">
<script src="{% static 'js/test.js' %}"></script>
<img src="{% static 'img/panda.jpg' %}" alt="加载失败">
模板标签
- 语法,由符号组合 {% %} 来定义单个的的成对出现的符号组{% tag %}{% endtag %}
- 常用标签的使用示例
# 传入一个list1 [i for i in range(1, 10)]
{# for 循环 #}
{% for i in list1 %}
{{ i }}
{% endfor %}
{# 条件循环 #}
{% for i in list1 %}
{% if i == 3 %}
现在是 i=3 的那次循环
{% endif %}
{% endfor %}
{# 外层循环计数 #}
{% for i in list1 %}
{% if forloop.counter == 3 %}
现在是第三次循环 {{ i }}
{% endif %}
{% endfor %}
{# 反向的外层循环计数,下表从大到小 #}
{% for i in list1 %}
{% if forloop.revcounter == 3 %}
{{ i }}
{% endif %}
{% endfor %}
{# 父级循环计数 #}
{% for i in list1 %}
{% for j in list1 %}
{% if forloop.parentloop.counter == 3 %}
{{ i }}, {{ j }} <br>
{% endif %}
{% endfor %}
{% endfor %}
{# 跳转使用 #}
# {% url "url_name" arg1 arg2 %} 其中需要在urls.py中定义页面的name属性
<a href="{% url 'ceshi2' %}">跳转</a>
{# 批量取消自动转义 #}
{% autoescape off %}
html
{% endautoescape %}
- 更多常用标签可以查看 defaulttags.py 源码
模板继承
- 模板的作用:当站点出现重复代码时候,使用模板对网站进行模块化操作,会使得网站的构造清晰明了,且省去了大量的不必要代码,为网站的搭建省却时间。
- base、block 和 extends
在模板的继承过程中,首要创建一个基类模板 “base.html”,使用block标签在需要被子模块覆盖的地方设置 block。在子模板中,使用 extends 标签进行模板继承,继承后使用 block 对基类中已设置的block进行页面填充。
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}
未命名的测试页面 {# 若该block没有填充则使用默认值 #}
{% endblock %}</title>
</head>
<body>
{#文章标题#}
{% block headline %}
{% endblock %}
{#文章内容#}
{% block content %}
{% endblock %}
{% block tail %}
{% endblock %}
</body>
</html>
需要进行继承的子页面
{% extends 'test/base.html' %}
{% block title %}
首页
{% endblock %}
{% block headline %}
<h3>无题</h3>
{% endblock %}
{% block content %}
<p>这是一篇文章,此文章有很多东西,但是不知道内容是什么</p>
<p>这是一篇文章,此文章有很多东西,但是不知道内容是什么</p>
{% endblock %}
{% block tail %}
<br>
结束了,不用看了
{% endblock %}
- block.super
对于继承的block内容,如需引用父类原本的内容,使用{{ block.super }}进行引用。
{% block title %}
{{ block.super }}首页
{% endblock %}
- include 标签
在 block 中引用外部页面的代码块
{% include 'test/test_templates.html' %}
- 总结:
- 模板的继承使用extends标签实现,通过使用block来子模板开放接口。
- extends 必须是模板中的第一个出现的标签
- 子模板中的所有内容,必须出现在父模板定义好的block中,否则django将不进行渲染
- 如果在某个block中要使用父模板的内容,用block.super获取
- 如果在某个block中需要引入外部页面的代码块,用include标签进行加载。