Django教程02-使用模板templates

上一篇: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


image.png

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é)果如下圖

image.png

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é)果如下:

image.png

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é)果如下:

image.png

(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)簽

參考:Django-內(nèi)置標(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)容。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末的榛,一起剝皮案震驚了整個(gè)濱河市琼了,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖雕薪,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昧诱,死亡現(xiàn)場離奇詭異,居然都是意外死亡所袁,警方通過查閱死者的電腦和手機(jī)盏档,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來燥爷,“玉大人蜈亩,你說我怎么就攤上這事∏棒幔” “怎么了稚配?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長港华。 經(jīng)常有香客問我道川,道長,這世上最難降的妖魔是什么立宜? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任冒萄,我火速辦了婚禮,結(jié)果婚禮上橙数,老公的妹妹穿的比我還像新娘尊流。我一直安慰自己,他們只是感情好灯帮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布崖技。 她就那樣靜靜地躺著,像睡著了一般钟哥。 火紅的嫁衣襯著肌膚如雪响疚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天瞪醋,我揣著相機(jī)與錄音忿晕,去河邊找鬼。 笑死银受,一個(gè)胖子當(dāng)著我的面吹牛践盼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宾巍,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼咕幻,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了顶霞?” 一聲冷哼從身側(cè)響起肄程,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤锣吼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蓝厌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玄叠,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年拓提,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了读恃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡代态,死狀恐怖寺惫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蹦疑,我是刑警寧澤西雀,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站歉摧,受9級(jí)特大地震影響蒋搜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜判莉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望育谬。 院中可真熱鬧券盅,春花似錦、人聲如沸膛檀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咖刃。三九已至泳炉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嚎杨,已是汗流浹背花鹅。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枫浙,地道東北人刨肃。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像箩帚,于是被迫代替她去往敵國和親真友。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355