Django 模板語言(譯)

聲明:轉(zhuǎn)載請注明出處http://www.reibang.com/p/1664dcfd840c

最近在折騰Django,看到官網(wǎng)的Django模板文章寫得挺詳細(xì)的,就想著翻譯下以加深自己的學(xué)習(xí)印象度帮,如果能幫助到大家我也會(huì)感到很欣慰,以下是譯文。

這篇文章主要講解了Django模板系統(tǒng)語法,如果你想了解更多關(guān)于Django模板如何工作以及如何擴(kuò)展的話痹栖,可以看這篇文章The Django template language: for Python programmers.

Django 模板語言意在強(qiáng)大和輕松之間取得平衡。這讓那些習(xí)慣用HTML的人感到很舒服瞭空。如果你有接觸過任何其他的基于文本的模板語言揪阿,比如 Smarty 或者 Jinja2,那么你應(yīng)該對Django的模板語言倍感親切疗我。

注意:
如果你有編程背景,或者習(xí)慣于那些混合代碼直接嵌入到HTML中的語言南捂,你要記住Django模板系統(tǒng)不是將Python簡單的嵌入HTML中吴裤。這是它設(shè)計(jì)的初衷:模板系統(tǒng)主要為了表達(dá)而不是程序邏輯。

Django模板系統(tǒng)提供了很多標(biāo)簽溺健,他們的方法很像一些程序結(jié)構(gòu)--if標(biāo)簽用于布爾判斷麦牺,for標(biāo)簽用于循環(huán)等等。但是這些不是簡單的作為相應(yīng)的Python代碼執(zhí)行矿瘦,模板系統(tǒng)不會(huì)執(zhí)行任意Python表達(dá)式枕面。只有下面列出的標(biāo)簽,過濾器缚去,以及語句是默認(rèn)支持的(但是你可以添加自定義模板標(biāo)簽和過濾器到模板語言如果有需要的話)

模板

模板就是一個(gè)簡單的文本文件,它可以生成任何文本格式(HTML,XML,CSV等)琼开。

模板中包含變量和標(biāo)簽易结,當(dāng)模板被執(zhí)行時(shí),變量會(huì)被賦值柜候,而標(biāo)簽是控制模板的邏輯的搞动。

下面是個(gè)演示了一些基礎(chǔ)知識的最小模板,稍后會(huì)講解其中的每個(gè)元素渣刷。

{% extends "base_generic.html" %}

{% block title %}{{ section.title }}{% endblock %}

{% block content %}
<h1>{{ section.title }}</h1>

{% for story in story_list %}
<h2>
  <a href="{{ story.get_absolute_url }}">
    {{ story.headline|upper }}
  </a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}

注意:
為什么我們要用基于文本的而不是基于XML的模板呢鹦肿?我們是想讓Django的模板語言用在更多的地方而不是僅僅在XML或HTML中。在聯(lián)網(wǎng)的世界里辅柴,我們把它用在電子郵箱箩溃,JavaScript以及CSV。你可以在任何文本格式中使用模板語言碌嘀。

哦涣旨,順便說下,讓人們編輯XML文件是很苦逼的股冗。

變量

變量看起來像這樣:{{ 變量名 }}霹陡,當(dāng)模板引擎遇到變量時(shí),會(huì)計(jì)算這個(gè)變量止状,并把結(jié)果賦值給它烹棉。變量名是由任何的數(shù)字,字母以及下劃線組成怯疤。點(diǎn)(“.”)也會(huì)出現(xiàn)在變量部分浆洗,當(dāng)然他有特殊用途,稍后會(huì)說明旅薄。特別注意的是辅髓,變量名中不能出現(xiàn)空格符以及任何的標(biāo)點(diǎn)符號泣崩。

上面說到點(diǎn)也會(huì)出現(xiàn)在變量部分,它的作用就是用來訪問變量的屬性的洛口。

背景

嚴(yán)格來講矫付,當(dāng)模板系統(tǒng)遇到點(diǎn)時(shí),它會(huì)根據(jù)以下的順序查找:

  • 字典查找
  • 屬性或方法查找
  • 數(shù)字索引查找

如果結(jié)果的值是可調(diào)用第焰,那么它就會(huì)被無參數(shù)調(diào)用买优。調(diào)用的結(jié)果就會(huì)變成模板中的值。

這個(gè)查找順序會(huì)對那些覆寫了字典查找的對象造成一些不可預(yù)期的行為挺举。比如下面是遍歷collections.defaultdict的代碼片:

{% for k, v in defaultdict.iteritems %}
   Do something with k and v here...
{% endfor %}

因?yàn)橄劝l(fā)生字典查找杀赢,所以這不可預(yù)期的行為就發(fā)生了,它會(huì)返回defaultdict的默認(rèn)值而不會(huì)調(diào)用它的iteritems()方法湘纵。在這個(gè)例子中脂崔,可以先轉(zhuǎn)化成字典。

在上面的模板例子中梧喷,{{ section.title }}會(huì)被section對象的title屬性代替砌左。

如果你調(diào)用的變量不存在,那么模板系統(tǒng)將默認(rèn)插入空字符串‘’

注意:如果模板的上下文(context)中傳入“bar”變量铺敌,而模板中存在{{ foo.bar }}表達(dá)式汇歹,那么該表達(dá)式僅僅具有字面意思,即調(diào)用foo的bar屬性偿凭,而不會(huì)調(diào)用context中“bar”的值产弹。

過濾器(FIlters)

你可以用filters來改變變量最終顯示的值。

過濾器看起來就像這樣{{ name|lower }}弯囊。這是將name變量通過lower過濾器全部轉(zhuǎn)換為小寫字母痰哨。|用來調(diào)用過濾器。

過濾器可以是鏈?zhǔn)降某V浚粋€(gè)過濾器的輸出會(huì)被用在下一個(gè)作谭。{{ text|escape|linebreaks }} 是一種通用的形式用來將文本內(nèi)容轉(zhuǎn)義,然后再轉(zhuǎn)為<P>標(biāo)簽以適用HTML奄毡。

有些過濾器帶參數(shù)折欠。如以下帶參過濾器:{{ bio|truncatewords:30 }}意思是只展示bio變量的前30個(gè)字符。

如果過濾器參數(shù)含有空格那么參數(shù)必須被引號引起來吼过;比如想要用逗號和空格將list中的元素拼接起來锐秦,你可以這樣{{ list|join:“, ”}}盗忱。

Django提供了大約60個(gè)內(nèi)置模板過濾器酱床。你可以到built-in filter reference.查閱更多的過濾器。為了讓你嘗試下趟佃,下面是一些常用的過濾器:

default

如果一個(gè)變量是false或者是空的扇谣,那么它的值就是你給的默認(rèn)值昧捷,否則就是變量本身的值。比如:

{{ value|default:"nothing" }}

如果變量value沒有提供罐寨,或者是空的話靡挥,上面就會(huì)顯示nothing

length

返回變量的長度鸯绿。這對于字符串和列表都起作用跋破。比如:

{{ value|length }}

如果 value是一個(gè)列表['a','b','c','d'],那么輸出就是4。

filesizeformat

將文件大小轉(zhuǎn)換為符合人們閱讀習(xí)慣的格式(如:‘13 KB’瓶蝴,‘4.1 MB’毒返,‘102 bytes’等)。如下:

{{ value|filesizeformat }}

如果value是123456789的話舷手,那么輸出將會(huì)是117.7MB拧簸。

重申下,這里僅是很少的例子聚霜,可以到built-in filter reference.查看更多完整列表狡恬。

當(dāng)然你也可以創(chuàng)建自定義模板過濾器,可以查閱這篇文章Custom template tags and filters.

提示
Django 的admin交互界面使用了所有的模板標(biāo)簽和過濾器蝎宇。你可以參考這篇文章The Django admin documentation generator.

標(biāo)簽(Tags)

標(biāo)簽的形式是 {% tag %}。標(biāo)簽比變量要更復(fù)雜:有些標(biāo)簽在輸出中創(chuàng)建文本祷安,有些通過展示循環(huán)和邏輯來控制流姥芥,有些引入額外的信息到模板中以供后續(xù)變量使用。

有些標(biāo)簽需要開頭和結(jié)尾(比如:{% tag %}...標(biāo)簽內(nèi)容...{% endtag %})

Django大約有兩打(24個(gè))內(nèi)置模板標(biāo)簽汇鞭。你可以查閱這篇文檔built-in tag reference.凉唐。以下僅列舉一些常用標(biāo)簽:

for

循環(huán)遍歷數(shù)組或列表,比如展示名為athete_list的運(yùn)動(dòng)員列表:

<ul>
{% for athlete in athlete_list %}
    <li>{{ athete.name }}</li>
{% endfor %}
</ul>

if,elif,else

{% if athlete_list %}
    Number of athletes: {{ athete_list|lengh }}
{% 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 }}變量來顯示列表長度。否則读整,如果athlete_in_locker_room_list列表不為空簿训,則顯示“Athletes should be out of the locker room soon!”信息。如果兩個(gè)列表都為空米间,則顯示“”No athletes.”强品。

你可以在if標(biāo)簽中使用過濾器以及進(jìn)行一系列的操作:

{% if athlete_list|length > 1 %}
   Team: {% for athlete in athlete_list %} ... {% endfor %}
{% else %}
   Athlete: {{ athlete_list.0.name }}
{% endif %}

當(dāng)上面的代碼運(yùn)行時(shí),注意大部分模板過濾器是以字符串類型返回的屈糊,所以上面過濾器返回的length是無法與數(shù)字1進(jìn)行比較的的榛。

block,extend

用于模板繼承(下面會(huì)講到)逻锐,一種 給力的方法可以在模板中減少樣板的使用夫晌。

再說下雕薪,上面僅是模板標(biāo)簽的一部分,查看更多內(nèi)容請移步至此built-intag reference

當(dāng)然你可以參考這篇文檔Custom template tags and filters來創(chuàng)建你自己的模板標(biāo)簽晓淀。

提示
Django 的admin交互界面使用了所有的模板標(biāo)簽和過濾器所袁。你可以參考這篇文章The Django admin documentation generator.

注釋

可以用{# #}來注釋模板中的某一行。

如下要糊,下面只有“hello”會(huì)在模板中起作用纲熏。

{# greeting #}hello

注釋中可以包含任何模板語句,如下:

{# {% if foo %}bar{% else %} #}

上述的注釋語句只能用于單行注釋({ # # }該注釋語句中不允許存在多行)锄俄。如果你想用多行注釋局劲,請移步至此注釋

模板繼承

在Django模板引擎中最給力也是最復(fù)雜的部分就是模板繼承。模板繼承可以使你建立一個(gè)包含網(wǎng)站所有公共元素的基本骨架奶赠,在里面可以定義一些區(qū)塊鱼填,模板的子模板可以重寫這些區(qū)塊。

下面的例子可以讓你更好的理解模板繼承:

<!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毅戈,定義了一個(gè)簡單的HTML骨架文檔苹丸,在一個(gè)簡單的兩列布局的頁面你也許會(huì)用到它。子模板要做的就是將內(nèi)容填充到空的區(qū)塊中苇经。

在這個(gè)例子中赘理,標(biāo)簽block定義了三個(gè)可以讓子模板重寫的區(qū)塊。每個(gè)block標(biāo)簽都會(huì)告訴模板引擎扇单,子模板可能會(huì)重寫該區(qū)塊商模。

下面我們定義了一個(gè)子模板:

{% extends "base.html" %}

{% block title %}My amazing blog{% endblock %}

{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

其中關(guān)鍵的地方是extends標(biāo)簽,這可以告訴模板引擎該模板是繼承于其他模板蜘澜。這樣當(dāng)模板系統(tǒng)執(zhí)行該模板時(shí)施流,就可以先定位他的父模板,上面模板的父模板就是“base.html”鄙信。

在該例中瞪醋,模板引擎會(huì)注意到在base.html中有三個(gè)block標(biāo)簽,然后會(huì)將子模板的內(nèi)容填充到父模板相應(yīng)的區(qū)塊中装诡。最后的結(jié)果如下({% block content %}區(qū)塊里具體的內(nèi)容是由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>

注意到银受,我們沒有在子模板中定義sidebar區(qū)塊,但還是有內(nèi)容慎王,沒錯(cuò)這是從父模板中來的蚓土。因此父模板的{%block%}標(biāo)簽中的內(nèi)容總是作為默認(rèn)值,赖淤,即假如子模板沒有重寫該區(qū)塊蜀漆,那么就默認(rèn)使用父模板中的內(nèi)容。

你可以根據(jù)需要采用多層繼承咱旱,一般來講我們采用的是三層繼承:

  • 首先創(chuàng)建一個(gè)包含網(wǎng)站主體外觀的基礎(chǔ)模板base.html
  • 為每部分的網(wǎng)頁創(chuàng)建名為base_部分名稱.html的模板确丢,比如绷耍,base_news.html,base_sports.html鲜侥。這些模板都是繼承base.html模板褂始,并且都有自己的設(shè)計(jì)樣式。
  • 為每一種類型的網(wǎng)頁創(chuàng)建個(gè)性化模板描函,比如新聞或者博客崎苗,它們都是繼承上述相應(yīng)的部分模板

上述的繼承方案可以極大化的重用你的代碼,并且方便擴(kuò)展舀寓。

以下是使用模板繼承需要注意的地方:

  • 如果你要在模板標(biāo)簽中使用{% extends %},那么它必須作為第一個(gè)模板標(biāo)簽胆数,否則模板繼承將失效。
  • 在你的基礎(chǔ)模板中多使用{ % block % }互墓。記住必尼,在子模板中不一定都要重寫父模板的block標(biāo)簽,所以你可以在父模板中多定義些block篡撵,在里面填充合理的默認(rèn)值判莉,這樣在子模板中你可以根據(jù)需要重寫相應(yīng)的block,其他的使用父模板的默認(rèn)值就可以了育谬。俗話說券盅,有備無患嗎。
  • 如果你發(fā)現(xiàn)在很多模板中有相同的內(nèi)容膛檀,那么你可以將這些相同的內(nèi)容提取出來放在父模板的block中渗饮。
  • 如果你想獲取父模板block中的內(nèi)容,你可以使用變量{{ block.super }}宿刮。如果你想要增加父模板block的內(nèi)容,而不是重寫它私蕾,那么這個(gè)變量將會(huì)非常有用僵缺。使用該變量插入的數(shù)據(jù)不會(huì)被自動(dòng)轉(zhuǎn)義(下面會(huì)提到),因?yàn)槿绻斜匾脑捤呀?jīng)在父模板中被轉(zhuǎn)以了踩叭。
  • 在{ % block % }標(biāo)簽外面用as標(biāo)簽創(chuàng)建的變量是無法在{ % block % }內(nèi)部使用的磕潮,如下,該模板不會(huì)顯示任何內(nèi)容:
{% trans "Title" as title %}
{% block content %}{{ title }}{% endblock %}
  • 另外容贝,你可以給 {% endblock %} 標(biāo)簽取任意名字自脯,比如:
{% block content %}
...
{% endblock content %}

在很大的模板中,這可以讓你知道哪個(gè)block標(biāo)簽正在關(guān)閉斤富。

最后膏潮,注意你不能在同一模板中定義相同名字的block標(biāo)簽,這是因?yàn)閎lock標(biāo)簽是雙向作用的满力,block標(biāo)簽不僅僅提供區(qū)域讓子模板填充焕参,它也可以在父模板中填充相應(yīng)的內(nèi)容轻纪。如果在模板中有相同名字的block標(biāo)簽,那么叠纷,父模板將不知道到底使用哪個(gè)block中的內(nèi)容來填充刻帚。

HTML自動(dòng)轉(zhuǎn)義

當(dāng)通過模板生成HTML時(shí),有個(gè)風(fēng)險(xiǎn)涩嚣,就是變量中可能存在一些特殊字符會(huì)影響HTML的結(jié)果崇众。比如,如下模板片段:

hello, {{ name }}

這從表面上看上去沒什么問題航厚,但是你需要考慮到顷歌,如果用戶的變量name輸入以下內(nèi)容會(huì)發(fā)生什么:

<script>alert('hello')</script>

如果name變量是以上內(nèi)容,那么最后HTML中會(huì)是這樣的結(jié)果:

Hello, <script>alert('hello')</script>

...這意味著瀏覽器會(huì)彈出一個(gè)腳本對話框阶淘!

類似的衙吩,如果name變量包含‘<’字符呢,比如這樣:

<b>username

這會(huì)導(dǎo)致網(wǎng)頁的剩余部分加粗溪窒。

顯然坤塞,用戶提交的數(shù)據(jù)是不能盲目信任的,并且不能直接插入到網(wǎng)頁中澈蚌,因?yàn)闀?huì)有惡意的用戶利用這種漏洞來干壞事摹芙。這種安全漏洞叫做跨站腳本攻擊(XSS)。

為了避免這個(gè)問題宛瞄,你有兩種選擇:

  • 一種浮禾,你可以利用escape過濾器來運(yùn)行每個(gè)不被信任的變量,這會(huì)把有潛在危險(xiǎn)的字符轉(zhuǎn)換為安全的份汗。當(dāng)然在Django推出的頭幾年盈电,這是一種默認(rèn)的解決方法。但是存在一個(gè)問題杯活,你需要確保每個(gè)變量都被轉(zhuǎn)義匆帚,顯然我們很容易漏掉一些數(shù)據(jù)。

  • 第二種旁钧,你可以利用Django的HTML自動(dòng)轉(zhuǎn)義機(jī)制吸重。這部分的剩余部分會(huì)講解自動(dòng)轉(zhuǎn)義是如何工作的。

在Django中歪今,每個(gè)模板都會(huì)默認(rèn)轉(zhuǎn)義每個(gè)變量嚎幸,以下是五個(gè)比較特別的字符轉(zhuǎn)義。

  • < 會(huì)被轉(zhuǎn)義成<
  • > 會(huì)被轉(zhuǎn)義成>
  • '(單引號)會(huì)被轉(zhuǎn)義成'
  • " (雙引號)會(huì)被轉(zhuǎn)義成"
  • & 會(huì)被轉(zhuǎn)義成&

在強(qiáng)調(diào)一遍寄猩,這種自動(dòng)轉(zhuǎn)義行為是默認(rèn)的嫉晶,當(dāng)你在使用Django的模板系統(tǒng)時(shí)你是受保護(hù)的。

如果關(guān)閉自動(dòng)轉(zhuǎn)義

如果你不想要數(shù)據(jù)被自動(dòng)轉(zhuǎn)義,比如你不想要某個(gè)網(wǎng)頁车遂,或者某個(gè)模板亦或者某個(gè)變量被轉(zhuǎn)義的話封断,你有幾個(gè)方法來關(guān)閉它。

為什么你會(huì)想關(guān)閉自動(dòng)轉(zhuǎn)義呢舶担?因?yàn)橛袝r(shí)候你想把原生的HTML語句嵌入到模板變量中坡疼,在這種情況下,你是不會(huì)想要將變量里的內(nèi)容轉(zhuǎn)義的衣陶。舉個(gè)例子柄瑰,你可能在數(shù)據(jù)庫中存了一點(diǎn)HTML,你想把它直接嵌入到模板中剪况〗陶矗或者,你可能正在用Django的模板系統(tǒng)生成非HTML文本译断,比如電子郵箱信息授翻。

關(guān)閉變量的自動(dòng)轉(zhuǎn)義

可以用safe過濾器來關(guān)閉單個(gè)變量的自動(dòng)轉(zhuǎn)義:

這會(huì)被轉(zhuǎn)義: {{ data }}
這不會(huì)被轉(zhuǎn)義: {{ data|safe }}

如果data變量中存在<b>,那么上面兩句輸出的結(jié)果是這樣的:

這會(huì)被轉(zhuǎn)義: <b>
這不會(huì)被轉(zhuǎn)義: <b>

關(guān)閉模板區(qū)塊的自動(dòng)轉(zhuǎn)義

為了控制模板的自動(dòng)轉(zhuǎn)義孙咪,需要在外面套一層autoescape標(biāo)簽堪唐,比如:

{% autoescape off %}
    Hello {{ name }}
{% endautoescape %}

你可以用on或者off來控制是否自動(dòng)轉(zhuǎn)義,如下例子:

Auto-escaping is on by default. Hello {{ name }}

{% autoescape off %}
    This will not be auto-escaped: {{ data }}.

    Nor this: {{ other_data }}
    {% autoescape on %}
        Auto-escaping applies again: {{ name }}
    {% endautoescape %}
{% endautoescape %}

自動(dòng)轉(zhuǎn)義標(biāo)簽會(huì)通過繼承來傳遞它的影響翎蹈,包括include標(biāo)簽淮菠。舉例:

以下是base.html

{% autoescape off %}
<h1>{% block title %}{% endblock %}</h1>
{% block content %}
{% endblock %}
{% endautoescape %}

以下是child.html

{% extends "base.html" %}
{% block title %}This & that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}

由于在base.html中自動(dòng)轉(zhuǎn)義是關(guān)閉的,在他的子模板child.html中也將是關(guān)閉的荤堪。如果greeting變量傳入字符串<b>Hello!</b>合陵,那么模板最終的結(jié)果將會(huì)是如下:

<h1>This & that</h1>
<b>Hello!</b>

注意事項(xiàng)

通常來講,我們不用過多的擔(dān)心自動(dòng)轉(zhuǎn)義澄阳。只有在寫views時(shí)或者自定義過濾器時(shí)需要注意自動(dòng)轉(zhuǎn)義拥知,并合理的標(biāo)記數(shù)據(jù)。所以盡情的使用模板吧碎赢。

如果你創(chuàng)建的模板在被使用時(shí)無法確定自動(dòng)轉(zhuǎn)義是否打開举庶,你可以添加escape過濾器到每個(gè)需要轉(zhuǎn)義的變量上。當(dāng)自動(dòng)轉(zhuǎn)義已開啟揩抡,escape過濾器對已轉(zhuǎn)義的變量進(jìn)行再次轉(zhuǎn)義并不會(huì)對該變量產(chǎn)生影響。

字符串與自動(dòng)轉(zhuǎn)義

在前面提到镀琉,過濾器的參數(shù)可以是字符串:

{{ data|default:"This is a string literal." }}

所有在模板中的字面上的字符串都不會(huì)經(jīng)過轉(zhuǎn)義--他們看上去像使用了safe過濾器峦嗤。這背后的原因是字符串內(nèi)容是由模板創(chuàng)建者決定的,所以他們可以確保文本是被正確轉(zhuǎn)義的屋摔。

也就是說你應(yīng)該這樣寫:

{{ data|default:"3 < 2" }}

而不是這樣:

{{ data|default:"3 < 2" }}  {# 別這樣寫烁设! #}

這不會(huì)影響變量data自身,變量的內(nèi)容在必要時(shí)仍然會(huì)被自動(dòng)轉(zhuǎn)義,因?yàn)檫@不是模板作者能控制的装黑。

訪問方法調(diào)用

大多數(shù)綁定在對象上的方法調(diào)用也存在于模板中副瀑。這意味著模板可以訪問的不僅僅是類的屬性以及從view中傳來的變量。舉個(gè)例子恋谭,Django的ORM(對象關(guān)系映射)框架提供個(gè)一個(gè)叫“entry_set”語法糠睡,這可以找到由外鍵關(guān)聯(lián)的對象集。所以如果模型“comment”有個(gè)外鍵關(guān)聯(lián)到模型“task”的話疚颊,你可以遍歷該task的所有comments:

{% for comment in task.comment_set.all %}
    {{ comment }}
{% endfor %}

類似的狈孔,QuerySets提供了一個(gè)叫count()的方法用來計(jì)算所包含對象的總個(gè)數(shù)。因此你可以得到關(guān)聯(lián)到task上的comment總和:

{{ task.comment_set.all.count }}

當(dāng)然你可以輕松的訪問你之前已經(jīng)定義過的模型中的方法:

models.py:

class Task(models.Model):
    def foo(self):
        return "bar"

template.html:

{{ task.foo }}

由于Django有意限制了模板語言中的邏輯處理材义,你不可以在方法中傳遞參數(shù)均抽,數(shù)據(jù)應(yīng)該在view處理,再傳入模板中展示其掂。

自定義標(biāo)簽和過濾器庫

一些應(yīng)用提供了自定義標(biāo)簽和過濾器的庫油挥,要想在模板中使用,請確保該應(yīng)用在INSTALLED_APPS(這里我添加了'django.contrib.humanize'庫)款熬,然后用load標(biāo)簽來加載:

{% load humanize %}

{{ 45000|intcomma }}

在上面例子中深寥,我們用load標(biāo)簽來加載humanize標(biāo)簽庫,這樣我們就可以使用該庫中的intcomma過濾器了华烟。如果你開啟了django.contrib.admindocs,你可以在admin站查詢文檔然后找出你安裝的自定義庫列表翩迈。

load標(biāo)簽后面可以跟多個(gè)庫名,當(dāng)中用空格隔開:

{% load humanize i18n %}

查看Custom template tags and filters文章來獲取更多關(guān)于自定義模板庫的信息盔夜。

自定義庫與模板繼承

當(dāng)你加載自定義標(biāo)簽或過濾器庫時(shí)负饲,這個(gè)庫中的標(biāo)簽以及過濾器只能在當(dāng)前模板使用,在其父模板或子模板是不起作用的喂链。

比如返十,有一個(gè)模板foo.html寫了{% load humanize %},其子模板中寫了{ % extends “foo.html” %}椭微,但子模板還是無法訪問父模板中humanize庫中的標(biāo)簽和過濾器的洞坑,要想訪問就必須在子模板中再次添加{% load humanize %}

這樣的特性主要是為了項(xiàng)目的維護(hù)性和邏輯性蝇率。

擴(kuò)展
模板參考
含內(nèi)置標(biāo)簽迟杂,內(nèi)置過濾器,使用其他模板本慕,語言排拷,以及更多其他內(nèi)容

官方原文:https://docs.djangoproject.com/en/1.11/ref/templates/language/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市锅尘,隨后出現(xiàn)的幾起案子监氢,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浪腐,死亡現(xiàn)場離奇詭異纵揍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)议街,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門泽谨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人傍睹,你說我怎么就攤上這事隔盛。” “怎么了拾稳?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵吮炕,是天一觀的道長。 經(jīng)常有香客問我访得,道長龙亲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任悍抑,我火速辦了婚禮鳄炉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搜骡。我一直安慰自己拂盯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布记靡。 她就那樣靜靜地躺著谈竿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪摸吠。 梳的紋絲不亂的頭發(fā)上空凸,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機(jī)與錄音寸痢,去河邊找鬼呀洲。 笑死,一個(gè)胖子當(dāng)著我的面吹牛啼止,可吹牛的內(nèi)容都是我干的道逗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼献烦,長吁一口氣:“原來是場噩夢啊……” “哼憔辫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起仿荆,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后拢操,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锦亦,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年令境,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了杠园。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舔庶,死狀恐怖抛蚁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惕橙,我是刑警寧澤瞧甩,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站弥鹦,受9級特大地震影響肚逸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜彬坏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一朦促、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧栓始,春花似錦务冕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至坯屿,卻和暖如春油湖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背领跛。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工乏德, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吠昭。 一個(gè)月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓喊括,卻偏偏與公主長得像,于是被迫代替她去往敵國和親矢棚。 傳聞我的和親對象是個(gè)殘疾皇子郑什,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354