2010-10-19 54 views
42

如果要覆蓋使用一個應用程序來在Django(在app /模板/應用/)在另一個目錄中創建一個同名的模板模板,該模板加載器檢查在應用程序的模板目錄之前。如果你只是想覆蓋模板的某些塊,你還必須複製整個模板並改變該塊,這實際上不是非常乾燥。Django的:重寫和擴展的應用程序模板

是否有人知道的方式來覆蓋orginial模板,而在同一時刻擴展它,這樣你只需要重寫你想改變的特定塊? (事情是這樣更改模板的名稱,因爲在某些情況下,你可能需要更改視圖,使其與其他模板工作)

編輯:正如亞當·泰勒在評論中指出,從Django 1.9 on了這一點是可能的,沒有任何黑客。

+0

@paulo:據我所知,大約有一般重寫應用程序的模板,當然文檔的,因爲這是日常工作,但我從來沒有見過任何東西關於擴展具有相同名稱的模板。如果您知道這是在文檔中,請將我指向該地點... – 2010-10-19 11:38:29

+0

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template – 2010-10-19 11:53:30

+1

此處的方法僅適用於特定於應用程序的管理模板,因爲這些模板將轉到與原始模板不同的路徑。Iguess這就是爲什麼這是在*管理*文檔,而不是在一般;) – 2011-09-14 16:19:43

回答

34

我覺得從this related question答案是相關的;目前,最好的解決方案似乎是使用來自django-apptemplates package on PyPI的自定義模板加載器,因此您只需使用pip即可安裝它(例如pip install django-apptemplates)。

模板加載器允許您在特定的應用程序中擴展模板;例如,延長管理inteface的索引頁,你會增加

'apptemplates.Loader', 

TEMPLATE_LOADERS列表settings.py,並使用

{% extends "admin:admin/index.html" %} 
在模板

+1

我正在使用這個片段來解決這個確切的問題。我感到驚訝的是,更多人沒有觸及它:一個想調整現有頁面部分的應用程序。 – 2012-02-02 00:59:20

+2

我認爲這是一個常見問題,但人們通過複製完整模板來製作。如果有人嘗試過,覆蓋和延伸通常以無限遞歸結束。這個問題在這張票上描述:https://code.djangoproject.com/ticket/15053 – Nagyman 2012-03-24 22:01:12

-1

[更新]

我誤解了問題,我原來的答覆僅適用於管理應用程序,它有一個內置的模板擴展機制。對於缺乏這種機制的其他應用程序,我只需分叉原始模板,而不是像自定義的模板加載器那樣擺弄選定的答案。如果你擔心分叉,你也可以實施一個擴展機制,如果你認爲它是值得的,那麼回饋到原始項目。


[原創答案]

直從細manual: 由於管理模板的模塊化設計,它通常是既無必要,也建議更換整個模板。只覆蓋模板中需要更改的部分幾乎總是更好。

繼續上面的例子中,我們要添加旁邊的歷史工具的頁面模型一個新的鏈接。在查看change_form.html之後,我們確定我們只需要重寫object-tools塊。因此,這裏是我們的新change_form.html:

{% extends "admin/change_form.html" %} 
{% load i18n %} 
{% block object-tools %} 
{% if change %}{% if not is_popup %} 
    <ul class="object-tools"> 
    <li><a href="history/" class="historylink">{% trans "History" %}</a></li> 
    <li><a href="mylink/" class="historylink">My Link</a></li> 
    {% if has_absolute_url %} 
     <li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink"> 
      {% trans "View on site" %}</a> 
     </li> 
    {% endif%} 
    </ul> 
{% endif %}{% endif %} 
{% endblock %} 

就是這樣!如果我們將這個文件放在templates/admin/my_app目錄中,我們的鏈接將出現在每個模型的更改表單上。

+0

感謝張貼這個,但我的問題不是關於管理模板。我正在尋找這樣的(前端)模板,例如。與第三方應用程序,我可能只是想改變一個塊,並複製整個休息,以覆蓋只是一個部分看起來像一些幹違反我... – 2010-10-19 12:10:37

+1

@lazerscience:這是相同的過程,除了在你的模板目錄,你應該遵守與你重寫的模板相同的目錄結構。檢查:http://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.loader.select_template – 2010-10-19 14:15:20

+4

我不認爲這仍然回答原來的問題。假設'niceapp.views.index()'使用模板'niceapp/index.html'。如果我想使用原始視圖但自定義模板,我可以在我的項目或我自己的應用程序的'templates'目錄中創建一個'niceapp/index.html'。但是,如何擴展原始並覆蓋一些塊,而不是複製整個模板?說'{%extend'niceapp/index.html「%}'顯然不能完成這項工作。 – akaihola 2010-10-27 08:11:05

2

在Django的維基,西蒙·威利森呈現a trick實現了「擴大自模板」的效果。但是,如果您使用app_directories模板加載器,則它不是直接適用的。

符號鏈接的應用程序的新目錄中的模板目錄可能做一招。

+0

謝謝,這也不是我正在尋找的100%,但我不認爲你能接近;在爲不同的網站定製模板時已經做了類似的事情! – 2010-10-27 11:13:31

-3

一個簡單的方法來做到這一點是這樣的:

比方說,你想擴展和覆蓋Django的/的contrib /管理/模板/管理/ change_form.html。

首先,將原始change_form.html複製到您的應用程序的模板目錄,並將其重命名爲類似myapp/templates/admin/original_change_form.html的內容。 (您也可以將其作爲符號鏈接來執行此操作。)

其次,在myapp/templates/admin中創建您自己的change_form.html。在它的頂部,把以下內容:

{% extends "admin/original_change_form.html" %} 

簡單!

+0

這實際上不是一個壞的解決方案,特別是如果你的系統支持符號鏈接。 – Flimm 2016-08-11 10:52:48

6

作爲一個更新,因爲這似乎是一個受歡迎的問題。我已經使用了overextends app,沒有任何問題。它提供了一個新的關鍵字overextends,允許擴展具有相同名稱的模板。

而且很容易與PIP安裝:

pip install -U django-overextends 
+0

哇,這是超級簡單和輕量級!愛它!謝謝! – 2014-10-30 18:08:58

+0

僅供參考Django 1.4的最新版本是0.3.2,後者需要1.7 – 2015-09-30 14:46:48

3

的Django 1.9及更高版本具有this feature

Django的模板加載器現在可以遞歸擴展模板。

所以你可以有從app1一個文件,內容是這樣的:

app1/templates/example/foobar.html

<p>I'm from app1</p> 
{% block main %}{% endblock %} 

而且你可以從app2文件擴展它(請注意,模板名稱example/foobar.html是相同):

app2/templates/example/foobar.html

{% extends "example/foobar.html" %} 
{% block main %} 
    <p>I'm from app2</p> 
{% endblock %} 

最終的結果應該是:

<p>I'm from app1</p> 
<p>I'm from app2</p> 
+0

我已經嘗試過這種設置,它似乎無法工作。 – HoHo 2016-09-29 15:25:08

+0

@HoHo你正在使用哪個Django版本? – Flimm 2016-10-03 08:43:36

+0

我使用的是1.10 - 如果'app1'有一組相互關聯的模板(比如'app1/templates/app1/base.html',它由'app1/templates/app1/subfolder/subsite.html'擴展) ,模板'app2'應該如何擴展這兩個模板?我想通過你的方法 - 在'app1'中複製文件夾層次結構和文件名的方法 - 可以工作,但看起來似乎不行。 – HoHo 2016-10-03 18:42:57