2009-09-11 135 views
73

我想在2個不同的基本文件中提供相同的內容。django模板:包含並擴展

所以我想這樣做:

page1.html:

{% extends "base1.html" %} 
{% include "commondata.html" %} 

page2.html:

{% extends "base2.html" %} 
{% include "commondata.html" %} 

的問題是,我似乎無法使用都延伸和包括。有沒有辦法做到這一點?如果不是,我怎麼能完成上述?

commondata.html將覆蓋在兩個base1.html和base2.html

這樣做的目的是在兩個PDF和HTML格式,其中的格式是稍有不同提供相同的頁中指定的塊。上面的問題雖然簡化了我想要做的事情,但如果我能得到答案,它將解決我的問題。

回答

83

當您使用擴展模板標記時,您說當前模板擴展了另一個 - 它是一個子模板,依賴於父模板。 Django會查看您的子模板並使用其內容來填充父級。

您想要在子模板中使用的所有內容都應該在Django用來填充父項的塊內。如果你想在子模板中使用include語句,你必須把它放在一個塊中,以便Django理解它。否則,它只是沒有意義,Django不知道如何處理它。

Django文檔有幾個非常好的使用塊代替父模板中塊的示例。爲什麼它沒有的情況下,工作對我來說

https://docs.djangoproject.com/en/dev/ref/templates/language/#template-inheritance

+1

我commondata.html中有定義的塊。但它並沒有取代父tempalte的塊...如果不是做一個include,我會在page1.html和page2.html中兩次寫入確切的數據,當然它的確行得通。但是我想把這個共同點分解爲commondata.html。 – 2009-09-11 04:17:16

+0

我會嘗試在一個塊內,但我想我以前嘗試過... – 2009-09-11 04:18:12

+0

似乎工作,我記得嘗試這一點,但我一定有一個錯字或什麼的時候導致它不工作。 – 2009-09-11 04:19:35

9

更多信息它有助於未來的人:

爲什麼它不工作的原因是,{%包含%}在Django沒有按」不喜歡像花哨的撇號這樣的特殊字符。我試圖包含的模板數據是從單詞中粘貼的。我不得不手動刪除所有這些特殊字符,然後成功包含它。

64

從Django文檔:

的包括標籤應被視爲實現「使這個子模板,幷包括HTML」,而不是「分析此子模板,包括它的內容,就好像它是一部分父母「。這意味着包含模板之間不存在共享狀態 - 每個包含都是完全獨立的呈現過程。

因此,Django不會從您的commondata.html中獲取任何塊,並且它不知道如何處理呈現的HTML以外的塊。

2

添加引用未來通過谷歌搜索到的人:您可能希望查看夾層庫爲此類情況提供的{%overextend%}標記。

3

您無法將包含文件的塊拖入子模板以覆蓋父模板的塊。但是,您可以在變量中指定父項,並在上下文中指定基本模板。

documentation

{%延伸變量%}用變量的值。如果變量的計算結果爲字符串,Django將使用該字符串作爲父模板的名稱。如果變量評估爲一個Template對象,Django將使用該對象作爲父模板。

代替單獨的「page1.html」和「page2.html」,將{% extends base_template %}放在「commondata.html」的頂部。然後在您看來,將base_template定義爲「base1.html」或「base2.html」。

1

編輯2015年12月10日:正如評論中指出的那樣,ssi自1.8版開始已被棄用。根據文檔:

此標記已被棄用,並將在Django 1.10中被刪除。改用include標籤。


在我看來,正確的(最好的)這個問題的答案是podshumok的一個,因爲它解釋了爲什麼有繼承一起使用時的行爲包括。

然而,我有點吃驚,沒有人提到由Django的模板系統,這是專門爲直列包括外部件文本的設計所提供的SSI標籤。這裏,內聯表示外部文本不會被解釋,解析或內插,而只是在呼叫模板內「複製」。

請參閱文檔以獲取更多詳細信息(請務必在頁面右下角的選擇器中檢查您的Django版本)。

https://docs.djangoproject.com/en/dev/ref/templates/builtins/#ssi

從文檔:

ssi 
Outputs the contents of a given file into the page. 
Like a simple include tag, {% ssi %} includes the contents of another file 
– which must be specified using an absolute path – in the current page 

也是這項技術的安全性問題,並且還所需ALLOWED_INCLUDE_ROOTS定義當心,必須添加到您的設置文件。

+1

請注意,從1.8開始,ssi已被棄用,以支持Include。 [https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#std:templatetag-include](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/# STD:templatetag-包括) – 2015-12-09 23:55:46

5

這應該爲你做竅門:把include標籤放在塊區域內。

page1.html:

{% extends "base1.html" %} 

{% block foo %} 
    {% include "commondata.html" %} 
{% endblock %} 

page2.html:

{% extends "base2.html" %} 

{% block bar %} 
    {% include "commondata.html" %} 
{% endblock %}