亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

詳解Python的Django框架中的模版繼承

2020-01-04 18:03:31
字體:
來源:轉載
供稿:網友

這篇文章主要介紹了詳解Python的Django框架中的模版繼承,就像Python中面對對象的方法繼承道理類似,需要的朋友可以參考下

在實際應用中,你將用 Django 模板系統來創建整個 HTML 頁面。 這就帶來一個常見的 Web 開發問題: 在整個網站中,如何減少共用頁面區域(比如站點導航)所引起的重復和冗余代碼?

解決該問題的傳統做法是使用 服務器端的 includes ,你可以在 HTML 頁面中使用該指令將一個網頁嵌入到另一個中。 事實上, Django 通過剛才講述的 {% include %} 支持了這種方法。 但是用 Django 解決此類問題的首選方法是使用更加優雅的策略—— 模板繼承 。

本質上來說,模板繼承就是先構造一個基礎框架模板,而后在其子模板中對它所包含站點公用部分和定義塊進行重載。

讓我們通過修改 current_datetime.html 文件,為 current_datetime 創建一個更加完整的模板來體會一下這種做法:

 

 
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  2. <html lang="en"
  3. <head> 
  4. <title>The current time</title> 
  5. </head> 
  6. <body> 
  7. <h1>My helpful timestamp site</h1> 
  8. <p>It is now {{ current_date }}.</p> 
  9.  
  10. <hr> 
  11. <p>Thanks for visiting my site.</p> 
  12. </body> 
  13. </html> 

這看起來很棒,但如果我們要為第三章的 hours_ahead 視圖創建另一個模板會發生什么事情呢?

 

 
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  2. <html lang="en"
  3. <head> 
  4. <title>Future time</title> 
  5. </head> 
  6. <body> 
  7. <h1>My helpful timestamp site</h1> 
  8. <p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p> 
  9.  
  10. <hr> 
  11. <p>Thanks for visiting my site.</p> 
  12. </body> 
  13. </html> 

很明顯,我們剛才重復了大量的 HTML 代碼。 想象一下,如果有一個更典型的網站,它有導航條、樣式表,可能還有一些 JavaScript 代碼,事情必將以向每個模板填充各種冗余的 HTML 而告終。

解決這個問題的服務器端 include 方案是找出兩個模板中的共同部分,將其保存為不同的模板片段,然后在每個模板中進行 include。 也許你會把模板頭部的一些代碼保存為 header.html 文件:

 

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

你可能會把底部保存到文件 footer.html :

 

 
  1. <hr> 
  2. <p>Thanks for visiting my site.</p> 
  3. </body> 
  4. </html> 

對基于 include 的策略,頭部和底部的包含很簡單。 麻煩的是中間部分。 在此范例中,每個頁面都有一個

My helpful timestamp site

標題,但是這個標題不能放在 header.html 中,因為每個頁面的

包含在頭部,我們就不得不包含

 

Django 的模板繼承系統解決了這些問題。 你可以將其視為服務器端 include 的逆向思維版本。 你可以對那些 不同 的代碼段進行定義,而不是 共同 代碼段。

第一步是定義 基礎模板 , 該框架之后將由 子模板 所繼承。 以下是我們目前所講述范例的基礎模板:

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  2. <html lang="en"
  3. <head> 
  4. <title>{% block title %}{% endblock %}</title> 
  5. </head> 
  6. <body> 
  7. <h1>My helpful timestamp site</h1> 
  8. {% block content %}{% endblock %} 
  9. {% block footer %} 
  10. <hr> 
  11. <p>Thanks for visiting my site.</p> 
  12. {% endblock %} 
  13. </body> 
  14. </html> 


這個叫做 base.html 的模板定義了一個簡單的 HTML 框架文檔,我們將在本站點的所有頁面中使用。 子模板的作用就是重載、添加或保留那些塊的內容。 (如果你一直按順序學習到這里,保存這個文件到你的template目錄下,命名為 base.html .)

我們使用一個以前已經見過的模板標簽: {% block %} 。 所有的 {% block %} 標簽告訴模板引擎,子模板可以重載這些部分。 每個{% block %}標簽所要做的是告訴模板引擎,該模板下的這一塊內容將有可能被子模板覆蓋。

現在我們已經有了一個基本模板,我們可以修改 current_datetime.html 模板來 使用它:

 

 
  1. {% extends "base.html" %} 
  2.  
  3. {% block title %}The current time{% endblock %} 
  4.  
  5. {% block content %} 
  6. <p>It is now {{ current_date }}.</p> 
  7. {% endblock %} 

再為 hours_ahead 視圖創建一個模板,看起來是這樣的:

 

 
  1. {% extends "base.html" %} 
  2.  
  3. {% block title %}Future time{% endblock %} 
  4.  
  5. {% block content %} 
  6. <p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p> 
  7. {% endblock %} 

看起來很漂亮是不是? 每個模板只包含對自己而言 獨一無二 的代碼。 無需多余的部分。 如果想進行站點級的設計修改,僅需修改 base.html ,所有其它模板會立即反映出所作修改。

以下是其工作方式。 在加載 current_datetime.html 模板時,模板引擎發現了 {% extends %} 標簽, 注意到該模板是一個子模板。 模板引擎立即裝載其父模板,即本例中的 base.html 。

此時,模板引擎注意到 base.html 中的三個 {% block %} 標簽,并用子模板的內容替換這些 block 。因此,引擎將會使用我們在 { block title %} 中定義的標題,對 {% block content %} 也是如此。 所以,網頁標題一塊將由 {% block title %}替換,同樣地,網頁的內容一塊將由 {% block content %}替換。

注意由于子模板并沒有定義 footer 塊,模板系統將使用在父模板中定義的值。 父模板 {% block %} 標簽中的內容總是被當作一條退路。

繼承并不會影響到模板的上下文。 換句話說,任何處在繼承樹上的模板都可以訪問到你傳到模板中的每一個模板變量。

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

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

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

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

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

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

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

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

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

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

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

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

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91影院在线免费观看视频| 亚洲网站在线看| 成人羞羞国产免费| 北条麻妃一区二区三区中文字幕| 欧美精品在线第一页| 精品久久久久久国产| 日本精品va在线观看| 欧美夜福利tv在线| 韩国欧美亚洲国产| 富二代精品短视频| 亚洲激情电影中文字幕| 国产精品日韩欧美综合| 中文字幕无线精品亚洲乱码一区| 欧美成人精品一区二区三区| 伦伦影院午夜日韩欧美限制| 九色91av视频| 国产丝袜精品第一页| 欧美激情第6页| 欧美精品久久久久久久久| 国产一区玩具在线观看| 欧美精品video| 一区二区三区高清国产| 久久久久久久久网站| 68精品国产免费久久久久久婷婷| 在线观看欧美视频| 粉嫩av一区二区三区免费野| 91中文在线观看| 国产欧美日韩中文字幕在线| 97欧美精品一区二区三区| 欧美黑人国产人伦爽爽爽| 欧美成人性生活| 97免费中文视频在线观看| 日本精品在线视频| 国产成人一区二区在线| 国产精品高清免费在线观看| 亚洲伊人一本大道中文字幕| 久久免费国产精品1| 亚洲欧美在线免费| 欧美亚洲另类视频| 在线观看日韩www视频免费| 日韩欧美在线视频观看| 亚洲国产女人aaa毛片在线| 国产欧美在线视频| 欧美精品videossex性护士| 最新国产成人av网站网址麻豆| 亚洲第一天堂无码专区| 一区二区三区无码高清视频| 亚洲最新中文字幕| 69**夜色精品国产69乱| 亚洲大胆人体av| 亚洲精品99久久久久中文字幕| 91国内揄拍国内精品对白| 欧美激情第1页| 91国产视频在线| 久久精品中文字幕一区| 欧美高清在线视频观看不卡| 一区二区国产精品视频| 亚洲天堂网站在线观看视频| 一区二区三区日韩在线| 午夜精品福利视频| 菠萝蜜影院一区二区免费| 日韩一区二区三区在线播放| 精品一区二区三区三区| 色综合久久中文字幕综合网小说| 精品亚洲一区二区三区在线观看| 亚洲性生活视频| 欧美有码在线观看视频| 97久久精品在线| 久久国产精品久久久| 欧美裸体xxxx极品少妇软件| 亚洲精品美女在线| 日韩欧中文字幕| 一区二区亚洲欧洲国产日韩| 日韩精品视频免费专区在线播放| 清纯唯美亚洲激情| 亚洲精品免费一区二区三区| 国产v综合ⅴ日韩v欧美大片| 91高清视频在线免费观看| 26uuu另类亚洲欧美日本老年| 亚洲欧美精品在线| 96sao精品视频在线观看| 亚洲精品自拍视频| 欧美激情视频网站| 国产在线999| 欧美日韩中文在线| 欧美成人精品一区| 欧美美女15p| 国产精品69av| 中文字幕精品www乱入免费视频| 国产精品成av人在线视午夜片| 日韩欧美主播在线| 欧美成人免费在线观看| 久久久精品久久| 欧美裸身视频免费观看| 免费91在线视频| 国产精品成人观看视频国产奇米| 国产精品极品美女粉嫩高清在线| 福利二区91精品bt7086| 亚洲国产精品va在看黑人| 欧美成年人视频网站欧美| www.久久草.com| 久久999免费视频| 国产精品第1页| 狠狠色狠狠色综合日日五| 亚洲精品国产精品国产自| 亚洲一区二区三区在线视频| 亚洲精品欧美一区二区三区| 日韩一级裸体免费视频| 久久精品成人一区二区三区| 成人精品视频在线| 国产精品成人在线| 日韩免费视频在线观看| 国产精品成人一区二区三区吃奶| 亚洲人a成www在线影院| 久久精品视频导航| 久久综合色影院| 国产欧美日韩中文字幕在线| 日韩电影大全免费观看2023年上| 日韩国产在线看| 亚洲毛片在线免费观看| 国产精品久久久久久久av大片| 亚洲国产小视频在线观看| 性欧美长视频免费观看不卡| 欧美专区中文字幕| 成人福利视频在线观看| 日韩二区三区在线| 爽爽爽爽爽爽爽成人免费观看| 久久亚洲一区二区三区四区五区高| 亚洲综合第一页| 日韩电影大全免费观看2023年上| 一区二区三区美女xx视频| 久久国产精品久久久久久| 精品视频一区在线视频| 色综合老司机第九色激情| 亚洲精品美女久久久| 久久99精品久久久久久青青91| 91精品在线观| 国产丝袜一区视频在线观看| 91综合免费在线| 国产精品入口福利| 日韩av手机在线看| 日韩av网址在线| 91亚洲精品在线观看| 久久中文字幕国产| 欧美综合一区第一页| 久久99精品国产99久久6尤物| 久久精品国产一区二区三区| 精品久久久久久亚洲国产300| 国产一区红桃视频| 国产精品夜色7777狼人| 亚洲黄色www| 一区二区三区久久精品| 国产亚洲免费的视频看| 黄色成人av网| 亚洲人成五月天| 欧美国产精品日韩| 国产精品入口日韩视频大尺度| 欧美亚洲第一页| 日韩免费观看在线观看| 日韩av毛片网| 欧美国产日韩一区二区在线观看| 超碰91人人草人人干| 成人精品福利视频| 国产欧美日韩中文字幕|