上一篇:Django教程01-創(chuàng)建一個(gè)django項(xiàng)目
下一篇:Django教程03-設(shè)計(jì)Models(使用數(shù)據(jù)庫)
上一章中无拗,我們?cè)陧憫?yīng)函數(shù)中返回了一個(gè)字符串。這章熊响,我們講如何使用模板旨别。
1.定義模板文件夾
首先在項(xiàng)目的根目錄建立項(xiàng)目的文件夾
#in dir "www"
mkdir templates
其次要在mysite(項(xiàng)目目錄)的settings.py中注冊(cè)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
注意:這里的DIRS要以絕對(duì)目錄的形式給出。
注意 如果設(shè)置里有 'APP_DIRS': True, 的話汗茄,如果應(yīng)用在INSTALLED_APPS中注冊(cè)過秸弛,那么應(yīng)用文件夾下的templates文件夾會(huì)被默認(rèn)搜索。
2.使用模板
首先將需要使用的模板文件放入模板文件夾templates
index.html的內(nèi)容為
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>使用模板</title>
</head>
<body>
這里使用了模板
</body>
</html>
在響應(yīng)函數(shù)中使用模板(views.py中)
from django.shortcuts import render
from django.shortcuts import HttpResponse
# Create your views here.
def index(request):
#return HttpResponse('Hello world!')
return render(request,'index.html')
訪問結(jié)果如下圖
3.使用模板變量
模板中的變量在view中給出洪碳,在模板中使用
模板中使用變量是用{{ }}將變量名環(huán)繞递览,例如{{name}}
我們修改上一步中的模板index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>使用模板</title>
</head>
<body>
{{content}}
</body>
</html>
home應(yīng)用的views.py中,給出變量的值
from django.shortcuts import render_to_response
def index(request):
content = '這里使用了模板的變量'
return render_to_response('index.html', {'content':content})
運(yùn)行結(jié)果如下:
views.py中也可以用下面的方式:
from django.shortcuts import render
def index(request):
content = '這里使用了模板的變量'
return render(request, 'index.html', {'content':content})
4.使用模板標(biāo)簽
參考:Django-Templates-built-in-tag-reference
(1)基本用法
模板標(biāo)簽使用{% %}環(huán)繞瞳腌,例如 {% comment "Optional note" %}
這里我們給出一個(gè)示例
模板index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>使用模板</title>
</head>
<body>
<ul>
{% for x in data %}
<li>
<h1>{{x.title}}</h1>
<p>{{x.content}}</p>
</li>
{% endfor %}
</ul>
</body>
</html>
在views.py中給出data的值
from django.shortcuts import render_to_response
def index(request):
data = [{'title':'春節(jié)放假通知','content':'春節(jié)放假通知內(nèi)容'},{'title':'習(xí)近平訪問美國','content':'習(xí)近平訪問美國詳情'},{'title':'96臺(tái)海危機(jī)','content':'96臺(tái)海危機(jī)詳情'}]
return render_to_response('index.html', {'data':data})
運(yùn)行結(jié)果如下:
(2)list與dict的解析
django使用jinjia2模板绞铃,不能實(shí)現(xiàn)list[N] 或 dict['key']的解析。
對(duì)于傳遞來的list嫂侍,要用{% for item in list %}來解析儿捧。
對(duì)于傳遞來的dict,可以用{% for key, value in dict.items %}來解析挑宠,或者直接使用{{dict.key}}來獲取值
(3)常見的集中標(biāo)簽
(A) for
循環(huán)組中的每一個(gè)項(xiàng)目菲盾,并讓這些項(xiàng)目在上下文可用。 舉個(gè)例子各淀,展示athlete_list中的每個(gè)成員懒鉴。
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
可以利用{% for obj in list reversed %}反向完成循環(huán)。
如果你需要循環(huán)一個(gè)包含列表的列表碎浇,可以通過拆分每一個(gè)二級(jí)列表為一個(gè)獨(dú)立變量來達(dá)到目的临谱。 舉個(gè)例子咆畏,如果你的內(nèi)容包括一個(gè)叫做points的(x,y) 列表,你可以像以下例子一樣輸出points列表:
{% for x, y in points %}
There is a point at {{ x }},{{ y }}
{% endfor %}
如果你想訪問一個(gè)字典中的項(xiàng)目吴裤,這個(gè)方法同樣有用。舉個(gè)例子:如果你的內(nèi)容包含一個(gè)叫做data的字典溺健,下面的方式可以輸出這個(gè)字典的鍵和值:
{% for key, value in data.items %}
{{ key }}: {{ value }}
{% endfor %}
for 標(biāo)簽帶有一個(gè)可選的{% empty %} 從句麦牺,以便在給出的組是空的或者沒有被找到時(shí),可以有所操作鞭缭。
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% empty %}
<li>Sorry, no athletes in this list.</li>
{% endfor %}
</ul>
(B)if
{% if %}會(huì)對(duì)一個(gè)變量求值剖膳,如果它的值是“True”(存在、不為空岭辣、且不是boolean類型的false值)吱晒,這個(gè)內(nèi)容塊會(huì)輸出
{% if athlete_list %}
Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
Athletes should be out of the locker room soon!
{% else %}
No athletes.
{% endif %}
上述例子中,如果athlete_list不為空沦童,就會(huì)通過使用{{ athlete_list|length }}過濾器展示出運(yùn)動(dòng)員的數(shù)量仑濒。
正如你所見,if標(biāo)簽之后可以帶有一個(gè)或者多個(gè){% elif %} 從句偷遗,也可以帶有一個(gè){% else %}從句以便在之前的所有條件不成立的情況下完成執(zhí)行墩瞳。這些從句都是可選的
(C)cycle
每當(dāng)這個(gè)標(biāo)簽被訪問,則傳出一個(gè)它的可迭代參數(shù)的元素。第一次訪問返回第一個(gè)元素,第二次訪問返回第二個(gè)參數(shù),以此類推.一旦所有的變量都被訪問過了氏豌,就會(huì)回到最開始的地方喉酌,重復(fù)下去
這個(gè)標(biāo)簽在循環(huán)中特別有用:
{% for o in some_list %}
<tr class="{% cycle 'row1' 'row2' %}">
...
</tr>
{% endfor %}
第一次迭代產(chǎn)生的HTML引用了 row1類,第二次則是row2類泵喘,第三次 又是row1 類泪电,如此類推。
你也可以使用變量纪铺,例如相速,如果你有兩個(gè)模版變量, rowvalue1和rowvalue2, 你可以讓他們的值像這樣替換:
{% for o in some_list %}
<tr class="{% cycle 'row1' rowvalue2 'row3' %}">
...
</tr>
{% endfor %}
在某些情況下,您可能需要連續(xù)引用一個(gè)當(dāng)前循環(huán)的值霹陡,而不前進(jìn)到下一個(gè)循環(huán)值和蚪。要達(dá)到這個(gè)目的,只需使用“as”來給{% cycle %}一個(gè)別名烹棉。從那時(shí)起(設(shè)置別名后)攒霹,你可以通過將別名作為一個(gè)模板變量進(jìn)行引用,從而隨意在模板中插入當(dāng)前循環(huán)的值浆洗。如果要將循環(huán)值移動(dòng)到獨(dú)立于原始cycle標(biāo)記的下一個(gè)值催束,可以使用另一個(gè)cycle標(biāo)記并指定變量的名稱。所以伏社,下面的模板:
<tr>
<td class="{% cycle 'row1' 'row2' as rowcolors %}">...</td>
<td class="{{ rowcolors }}">...</td>
</tr>
<tr>
<td class="{% cycle rowcolors %}">...</td>
<td class="{{ rowcolors }}">...</td>
</tr>
將輸出:
<tr>
<td class="row1">...</td>
<td class="row1">...</td>
</tr>
<tr>
<td class="row2">...</td>
<td class="row2">...</td>
</tr>
5.模板繼承
參考:Django-模板繼承
(1)模板用法
模板繼承涉及到模板標(biāo)簽 block extends
Django模版引擎中最強(qiáng)大也是最復(fù)雜的部分就是模版繼承了抠刺。模版繼承可以讓您創(chuàng)建一個(gè)基本的“骨架”模版塔淤,它包含您站點(diǎn)中的全部元素,并且可以定義能夠被子模版覆蓋的 blocks 速妖。
通過從下面這個(gè)例子開始高蜂,可以容易的理解模版繼承:通過從下面這個(gè)例子開始,可以容易的理解模版繼承:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>{% block title %}My amazing site{% 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>
這個(gè)模版罕容,我們把它叫作 base.html备恤,并保存在templates文件夾中。它定義了一個(gè)可以用于兩列排版頁面的簡單HTML骨架锦秒÷恫矗“子模版”的工作是用它們的內(nèi)容填充空的blocks。
在這個(gè)例子中旅择, block 標(biāo)簽定義了三個(gè)可以被子模版內(nèi)容填充的block惭笑。 block 告訴模版引擎: 子模版可能會(huì)覆蓋掉模版中的這些位置。
子模版可能看起來是這樣的:
{% extends "base.html" %}/span>
{% block title %}My amazing blog{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
extends 標(biāo)簽是這里的關(guān)鍵生真。它告訴模版引擎沉噩,這個(gè)模版“繼承”了另一個(gè)模版。當(dāng)模版系統(tǒng)處理這個(gè)模版時(shí)汇歹,首先屁擅,它將定位父模版——在此例中,就是“base.html”产弹。
那時(shí)派歌,模版引擎將注意到 base.html 中的三個(gè) block 標(biāo)簽,并用子模版中的內(nèi)容來替換這些block痰哨。根據(jù) blog_entries 的值胶果,輸出可能看起來是這樣的:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>My amazing blog</title>
</head>
<body>
<div id="sidebar">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
</div>
<div id="content">
<h2>Entry one</h2>
<p>This is my first entry.</p>
<h2>Entry two</h2>
<p>This is my second entry.</p>
</div>
</body>
</html>
請(qǐng)注意,子模版并沒有定義 sidebar block斤斧,所以系統(tǒng)使用了父模版中的值早抠。父模版的 {% block %} 標(biāo)簽中的內(nèi)容總是被用作備選內(nèi)容(fallback)。
(2)多級(jí)繼承
您可以根據(jù)需要使用多級(jí)繼承撬讽。使用繼承的一個(gè)常用方式是類似下面的三級(jí)結(jié)構(gòu):
- 創(chuàng)建一個(gè) base.html 模版來控制您整個(gè)站點(diǎn)的主要視覺和體驗(yàn)蕊连。為您的站點(diǎn)的每一個(gè)“分支”創(chuàng)建一個(gè)base_SECTIONNAME.html 模版。例如游昼, base_news.html, base_sports.html甘苍。這些模版都繼承自 base.html ,并且包含了每部分特有的樣式和設(shè)計(jì)烘豌。
- 為每一種頁面類型創(chuàng)建獨(dú)立的模版载庭,例如新聞內(nèi)容或者博客文章。這些模版繼承對(duì)應(yīng)分支的模版。
- 這種方式使代碼得到最大程度的復(fù)用囚聚,并且使得添加內(nèi)容到共享的內(nèi)容區(qū)域更加簡單靖榕,例如分支范圍內(nèi)的導(dǎo)航。
(2)模板使用注意事項(xiàng)
這里是使用繼承的一些提示:
如果你在模版中使用 {% extends %} 標(biāo)簽顽铸,它必須是模版中的第一個(gè)標(biāo)簽茁计。其他的任何情況下,模版繼承都將無法工作谓松。
在base模版中設(shè)置越多的 {% block %} 標(biāo)簽越好簸淀。請(qǐng)記住,子模版不必定義全部父模版中的blocks毒返,所以,你可以在大多數(shù)blocks中填充合理的默認(rèn)內(nèi)容舷手,然后拧簸,只定義你需要的那一個(gè)。多一點(diǎn)鉤子總比少一點(diǎn)好男窟。
如果你發(fā)現(xiàn)你自己在大量的模版中復(fù)制內(nèi)容盆赤,那可能意味著你應(yīng)該把內(nèi)容移動(dòng)到父模版中的一個(gè) {% block %} 中。
如果需要獲取父模板中的block 的內(nèi)容歉眷,可以使用{{ block.super }} 變量牺六。如果你想要在父block 中新增內(nèi)容而不是完全覆蓋它,它將非常有用汗捡。使用{{ block.super }} 插入的數(shù)據(jù)不會(huì)被自動(dòng)轉(zhuǎn)義(參見下一節(jié))淑际,因?yàn)楦改0逯械膬?nèi)容已經(jīng)被轉(zhuǎn)義。
為了更好的可讀性扇住,你也可以給你的 {% endblock %} 標(biāo)簽一個(gè) 名字 春缕。例如:
{% block content %}
...
{% endblock content %}
在大型模版中,這個(gè)方法幫你清楚的看到哪一個(gè) {% block %} 標(biāo)簽被關(guān)閉了艘蹋。
- 最后锄贼,請(qǐng)注意不能在一個(gè)模版中定義多個(gè)相同名字的block 標(biāo)簽。這個(gè)限制的存在是因?yàn)閎lock標(biāo)簽的作用是“雙向”的女阀。這個(gè)意思是宅荤,block 標(biāo)簽不僅提供了一個(gè)坑去填,它定義向父模版的坑中所填的內(nèi)容浸策。如果在一個(gè)模版中有兩個(gè)名字一樣的 block 標(biāo)簽冯键,模版的父模版將不知道使用哪個(gè)block的內(nèi)容。