模板(template)包含與繼承


  Django 模板查找機制: Django 查找模板的過程是在每個 app 的 templates 文件夾中找(而不只是當前 app 中的代碼只在當前的 app 的 templates 文件夾中找)。各個 app 的 templates 形成一個文件夾列表,Django 遍歷這個列表,一個個文件夾進行查找,當在某一個文件夾找到的時候就停止,所有的都遍歷完了還找不到指定的模板的時候就是 Template Not Found (過程類似於Python找包)。這樣設計有利當然也有弊,有利是的地方是一個app可以用另一個app的模板文件,弊是有可能會找錯了。所以我們使用的時候在 templates 中建立一個 app 同名的文件夾,這樣就好了。

  這就需要把每個app中的 templates 文件夾中再建一個 app 的名稱,僅和該app相關的模板放在 app/templates/app/ 目錄下面。

  例:aptest/templates/aptest,模板調用:return render(request,'aptest/hours_ahead.html',context)

 

項目aptest下的templates文件夾用於存放所有模板:

base.html,header.html,footer.html放於templates目錄下

current_datetime.html,hours_ahead.html放於templates/aptest目錄下

base.html:定義了一個簡單的 HTML 框架文檔,該站點下所有項目都將使用

<!-- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head> -->  <!--注釋掉該部分內容,使用header.html中的內容替代 --> {% include 'header.html' %} <!-- include的.html要與其位於同一目錄下 --> <title>{% block title %}{% endblock %}</title>   <!--  {% block %} 標簽告訴模板引擎,子模板可以重載這些部分。 每個{% block %}標簽所要做的是告訴模板引擎,該模板下的這一塊內容將有可能被子模板覆蓋。 -->
</head>
<body>
    <h1>My helpful timestamp site</h1> {% block content %}{% endblock %}
    {% block footer %}   <!-- 由於子模板並沒有定義 footer 塊,模板系統將使用在父模板中定義的值。 父模板 {% block %} 標簽中的內容總是被當作一條退路。--> <hr>
    <p>Thanks for visiting my site2.</p>
    {% endblock %}
    <!-- {% include 'footer.html' %} -->
</body>
</html>

header.html內容:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>

footer.html內容:(該base.html中未調用)

    <hr>
    <p>Thanks for visiting my siteffffff.</p>
</body>
</html>

 

current_datetime.html內容:

{% extends "base.html" %} <!-- 注明擴展base.html --> {% block title %}The current time{% endblock %} <!-- 擴展base中的block title部分 -->

{% block content %}  <!-- 擴展base中的block content部分 -->
<p>It is now current_aadate.</p>
{% endblock %}

hours_ahead.html內容:

{% extends "base.html" %}

{% block title %}Future time{% endblock %} {% block content %} <p>In {{ hour_offset }} hour(s), it will be  next_time .</p>
{% endblock %}

 

最后在view中渲染current_datetime.html,hours_ahead.html,分別顯示如下:

from:http://djangobook.py3k.cn/2.0/chapter04/

可以根據需要使用任意多的繼承次數。 使用繼承的一種常見方式是下面的三層法:

創建 base.html 模板,在其中定義站點的主要外觀感受。 這些都是不常修改甚至從不修改的部分。

為網站的每個區域創建 base_SECTION.html 模板(例如, base_photos.html 和 base_forum.html )。這些模板對 base.html 進行拓展,並包含區域特定的風格與設計。1

為每種類型的頁面創建獨立的模板,例如論壇頁面或者圖片庫。 這些模板拓展相應的區域模板。

這個方法可最大限度地重用代碼,並使得向公共區域(如區域級的導航)添加內容成為一件輕松的工作。

 

以下是使用模板繼承的一些訣竅:

如果在模板中使用 {% extends %} ,必須保證其為模板中的第一個模板標記。 否則,模板繼承將不起作用。3

一般來說,基礎模板中的 {% block %} 標簽越多越好。 記住,子模板不必定義父模板中所有的代碼塊,因此你可以用合理的缺省值對一些代碼塊進行填充,然后只對子模板所需的代碼塊進行(重)定義。 俗話說,鈎子越多越好。4

如果發覺自己在多個模板之間拷貝代碼,你應該考慮將該代碼段放置到父模板的某個 {% block %} 中。

如果你需要訪問父模板中的塊的內容,使用 {{ block.super }}這個標簽吧,這一個魔法變量將會表現出父模板中的內容。 如果只想在上級代碼塊基礎上添加內容,而不是全部重載,該變量就顯得非常有用了。14

不允許在同一個模板中定義多個同名的 {% block %} 。 存在這樣的限制是因為block 標簽的工作方式是雙向的。 也就是說,block 標簽不僅挖了一個要填的坑,也定義了在父模板中這個坑所填充的內容。如果模板中出現了兩個相同名稱的 {% block %} 標簽,父模板將無從得知要使用哪個塊的內容。4

{% extends %} 對所傳入模板名稱使用的加載方法和 get_template() 相同。 也就是說,會將模板名稱被添加到 TEMPLATE_DIRS 設置之后。3

多數情況下, {% extends %} 的參數應該是字符串,但是如果直到運行時方能確定父模板名,這個參數也可以是個變量。 這使得你能夠實現一些很酷的動態功能。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM