- 注意:
- 1. Django 模板
- 2. Django 模板-抽取通用模板 base.html的应用
- 3. Django 模板查找机制
- 4. 模板进阶-传递字符/列表/字典到html
- 5. 模板进阶-条件判断与for循环
- 6. 模板进阶-得到视图对应的网址
- 7. 模板进阶-逻辑操作
无意中在网上发现了这个网站自强学堂(作者还是校友),上面整理的教程都很不错,正好适合刚学完DjangoBasic篇之后的扩展。本系列作为该自强学堂教程的笔记,为节省时间,与DjangoBasic部分重叠的话,会省略。
注意:
Django的标签导致Jekyll无法编译,都修改为了[%
和[{
,使用时需要替换将[
替换为{
!
1. Django 模板
- 按之前的步骤,新建app,并在settings.INSTALLED_APPS中加入
'learn',
。 - 打开
learn/views.py
写一个首页的视图
def index(request):
return render(request, 'home.html')
- learn目录下新建一个
templates
文件夹,里面新建一个home.html
,加入如下代码。
<!DOCTYPE html>
<html>
<head>
<title>欢迎光临</title>
</head>
<body>
欢迎光临自强学堂
</body>
</html>
-
project的url解析中添加
url(r'^$', index, name='home'),
。 -
访问
http://localhost:8000/
,能看到上面的home.html。
客户通过url访问 -> project的url解析 -> 对应的view -> view返回html
2. Django 模板-抽取通用模板 base.html的应用
网站模板的设计,一般的,我们做网站有一些通用的部分,比如 导航,底部,访问统计代码等等,我们将这三个部分抽取出来,作为通用部分.
- 在templates文件夹下新建:nav.html, bottom.html, tongji.html。
作为实例,在每个html中输入
<h1>☓☓☓</h1>
- 写一个 base.html 来包含这些通用文件(include)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>[% block title %}默认标题[% endblock%} - 自强学堂</title>
</head>
<body>
[% include 'nav.html'%}
[% block content %}
<div> 这里是默认部分,如果不覆盖就显示这里的默认内容</div>
[% endblock %}
[% include 'bottom.html'%}
[% include 'tongji.html'%}
</body>
</html>
- 首页 home.html,继承或者说扩展(extends)原来的 base.html。
[% extends 'base.html' %}
[% block title %} 欢迎光临首页 [% endblock %}
[% block content %}
<h1>这里是首页,欢迎光临</h1>
[% include 'ad.html' %}
[% endblock %}
上面ad.html是广告用页面,需要新建。
- 访问
http://localhost:8000/
,能看到的home.html。
注意:目前我们将模板文件,全部放在templates文件夹下面,Django会去这个文件夹中查找。但是如果如果每个app中的template都有同样的名称的html呢?这样Django就不一定能找到对应的文件了,因为Django并不能从当前app的文件夹中查找。
3. Django 模板查找机制
Django 模板查找机制: Django 查找模板的过程是在每个 app 的 templates 文件夹中找(而不只是当前 app 中的代码只在当前的 app 的 templates 文件夹中找)。各个 app 的 templates 形成一个文件夹列表,Django 遍历这个列表,一个个文件夹进行查找,当在某一个文件夹找到的时候就停止,所有的都遍历完了还找不到指定的模板的时候就是 Template Not Found (过程类似于Python找包)。这样设计有利当然也有弊,有利是的地方是一个app可以用另一个app的模板文件,弊是有可能会找错了。所以我们使用的时候在 templates 中建立一个 app 同名的文件夹,这样就好了。
- 把每个app中的 templates 文件夹中再建一个 app 的名称,仅和该app相关的模板放在 app/templates/app/ 目录下面。
zqxt
├── tutorial
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── templates
│ │ └── tutorial
│ │ ├── home.html
│ │ └── search.html
│ ├── tests.py
│ └── views.py
├── learn
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── templates
│ │ └── learn
│ │ ├── home.html
│ │ └── base.html
│ │ └── ad.html
│ │ └── bottom.html
│ │ └── nav.html
│ │ └── tongji.html
│ ├── tests.py
│ └── views.py
├── manage.py
└── zqxt
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
- 再修改没处引用到html文件的地方,比如将
base.html
修改为learn\base.html
,都是相对于templates目录下的路径。 这样即使html名重复,也能查找到唯一的html文件了。
4. 模板进阶-传递字符/列表/字典到html
- 传递字符给html
def index(request):
return render(request, 'learn\home.html',{"mystring":"yes,hello"})
<h1><font color="red">[{mystring}}</font></h1>
最终在页面上能显示出红色的字符串。
- 传递列表给html
def index(request):
mylist = ["html","css","js","python"]
return render(request, 'learn\home.html',{"mylist":mylist})
[% for i in mylist %}
<h1><font color="red">[{i}}</font></h1>
[% endfor %}
- 传递字典给html
def index(request):
mydict = {"name":u"lijun","gender":u"male"}
return render(request, 'learn\home.html',{"mydict":mydict})
[% for key,value in mydict.items %}
<h1><font color="red">[{key}}: [{ value }}</font></h1>
[% endfor %}
或者使用
<h1><font color="red">姓名: [{ mydict.name }}</font></h1>
<h1><font color="red">性别: [{ mydict.gender }}</font></h1>
5. 模板进阶-条件判断与for循环
- 创建一个长度100的List,并for循环显示
def index(request):
List = map(str, range(100)) # 一个长度为100的 List
return render(request, 'learn\home.html',{"List":List})
[% for item in List %}
<font color="red">[{item}},</font>
[% endfor %}
但是上面的显示,会导致每个数字后面都有,
分割,显然最后一个字符后面是不需要的。
修改上面的html为如下,如果是最后一个字符用句号,否则用逗号:
[% for item in List %}
<font color="red">[{item}}
[% if forloop.last %}
。
[% else %}
,
[% endif %}
</font>
[% endfor %}
- 在for循环中还有很多有用的东西,如
变量 | 描述 |
---|---|
forloop.counter | 索引从 1 开始算 |
forloop.counter0 | 索引从 0 开始算 |
forloop.revcounter | 索引从最大长度到 1 |
forloop.revcounter0 | 索引从最大长度到 0 |
forloop.first | 当遍历的元素为第一项时为真 |
forloop.last | 当遍历的元素为最后一项时为真 |
forloop.parentloop | 用在嵌套的 for 循环中,获取上一层 for 循环的 forloop |
- 当列表中可能为空值时用 for empty
<ul>
[% for athlete in athlete_list %}
<li>[{ athlete.name }}</li>
[% empty %}
<li>抱歉,列表为空</li>
[% endfor %}
</ul>
例如可以这样使用 <font color="red">第[{ forloop.counter}}个元素:[{item}}</font>
。
6. 模板进阶-得到视图对应的网址
- 在复习下通过name链接到url,如下代码:
- views中添加:
def add(request, a, b):
c = int(a) + int(b)
return HttpResponse(str(c))
-
url解析中添加
url(r'^add/(\d+)/(\d+)/$', add, name='add'),
-
模板文件中:
[% for item in List %}
<a href="[% url 'add' item item %}">add me </a>
<font color="red">第[{ forloop.counter}}个元素:[{item}}</font>
[% endfor %}
上述过程,实现点击上面的url后,生成显示的url,并跳转到对应的add view中处理。
- 给网址取别名,便于多个地方使用,修改html文件
[% url 'add' item item as the_url %}
<a href="[{ the_url }}"> 链接到:[{ the_url }}</a>
页面上显示为 链接到:/add/0/0/
7. 模板进阶-逻辑操作
==, !=, >=, <=, >, <
,这些逻辑操作符,都可以使用,比如:
[% if num <= 100 and num >= 0 %}
num在0到100之间
[% else %}
数值不在范围之内!
[% endif %}
[% if 'ziqiangxuetang' in List %}
自强学堂在名单中
[% endif %}