官方文檔css
你可能已經注意到咱們在例子視圖中返回文本的方式有點特別。 也就是說,HTML被直接硬編碼在 Python代碼之中。html
def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
儘管這種技術便於解釋視圖是如何工做的,但直接將HTML硬編碼到你的視圖裏卻並非一個好主意。 讓咱們來看一下爲何:前端
對頁面設計進行的任何改變都必須對 Python 代碼進行相應的修改。 站點設計的修改每每比底層 Python 代碼的修改要頻繁得多,所以若是能夠在不進行 Python 代碼修改的狀況下變動設計,那將會方便得多。python
Python 代碼編寫和 HTML 設計是兩項不一樣的工做,大多數專業的網站開發環境都將他們分配給不一樣的人員(甚至不一樣部門)來完成。 設計者和HTML/CSS的編碼人員不該該被要求去編輯Python的代碼來完成他們的工做。程序員
程序員編寫 Python代碼和設計人員製做模板兩項工做同時進行的效率是最高的,遠勝於讓一我的等待另外一我的完成對某個既包含 Python又包含 HTML 的文件的編輯工做。npm
基於這些緣由,將頁面的設計和Python的代碼分離開會更乾淨簡潔更容易維護。 咱們可使用 Django的 模板系統 (Template System)來實現這種模式,這就是本章要具體討論的問題。django
只要是在html裏面有模板語法就不是html文件了,這樣的文件就叫作模板。bootstrap
官方文檔的定義:後端
模板就是一個簡單的文本文件,它能夠生成任何文本格式(HTML,XML,CSV等)。瀏覽器
模板中包含變量和標籤,當模板被執行時,變量會被賦值,而標籤是控制模板的邏輯的。
(1)變量:{{}} {{ 變量名 }}
(2)標籤:{% %} {% tag %}.
模板語法由render()渲染的.
瀏覽器接收到的數據是已經通過渲染以後的數據
變量看起來像這樣:{{ 變量名 }}
,當模板引擎遇到變量時,會計算這個變量,並把結果賦值給它。變量名是由任何的數字,字母以及下劃線組成。點(「.」)也會出如今變量部分,固然他有特殊用途,稍後會說明。特別注意的是,變量名中不能出現空格符以及任何的標點符號。
上面說到點也會出如今變量部分,它的做用就是用來訪問變量的屬性的。
1 <body> 2 <p>變量渲染各類數據類型</p> 3 <ul> 4 <li>name:{{ name }}</li> 5 <li>age:{{ age }}</li> 6 <li>student{{ student }}</li> 7 </ul> 8 </body>
1 def index(request): 2 name = 'lilz' #str 3 age = 20 #int 4 student=['egon','wusir','yaoshen'] #list 5 return render(request,'index.html',{'name':name,'age':age,'student':student})
測試:
使用句點符(.)一層一層往裏層查詢
仍是上面的案例:文件不作修改,只更改index.html中的
<li>student:{{ student.0 }}</li>
那麼測試結果
那麼若是須要傳的很是多的參數時,locals代替傳變量的參數
name = 'lilz' #str age = 20 #int student=['egon','wusir','yaoshen'] #list return render(request,'index.html',{'name':name,'age':age,'student':student}) return render(request,'index.html',locals()) #效果和上面的相同
做用:
過濾器轉換變量和標記參數的值。簡言之,把原本的數據在根據規則過濾一遍。
語法:
{{var|filter_name:參數}} ---{{變量|過濾器名:參數}}
請參考博客:Django-模板語法-過濾器
標籤看起來像是這樣的: {% tag %}
。標籤比變量更加複雜:一些在輸出中建立文本,一些經過循環或邏輯來控制流程,一些加載其後的變量將使用到的額外信息到模版中。一些標籤須要開始和結束標籤 (例如{% tag %} ...
標籤 內容 ... {% endtag %})
請參考博文:Django-模板語法-標籤
Django模版引擎中最強大也是最複雜的部分就是模版繼承了。模版繼承可讓您建立一個基本的「骨架」模版,它包含您站點中的所有元素,而且能夠定義可以被子模版覆蓋的 blocks 。
咱們下面的計劃是作一個母版,讓其餘子模板頁面可以繼承母版
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> 7 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" 8 integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> 9 <style> 10 * { 11 padding: 0; 12 margin: 0; 13 } 14 15 .header { 16 width: 100%; 17 height: 50px; 18 background-color: #369; 19 } 20 </style> 21 </head> 22 <body> 23 <div class="header"></div> 24 <div class="container"> 25 <div class="row"> 26 <div class="col-md-3"> 27 <div class="panel panel-success"> 28 <div class="panel-body"> 29 30 </div> 31 <div class="panel-footer"> 32 <p><a href="/app01/order/">訂單</a></p> 33 <p><a href="">商品信息</a></p> 34 <p><a href="">價格</a></p> 35 <p><a href="">走勢</a></p> 36 </div> 37 </div> 38 </div> 39 <div class="col-md-9"> 40 41 <div class=""> 42 {% block content %} 43 <h3>welcome !</h3> 44 {% endblock %} 45 </div> 46 </div> 47 48 </div> 49 </div> 50 </body> 51 </html>
1 {% extends 'base.html' %} 2 3 {% block content %} 4 <div class="jumbotron"> 5 <h1>Hello, world!</h1> 6 <p>...</p> 7 <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p> 8 </div> 9 {% endblock %}
1 {% extends 'base.html' %} 2 3 {% block content %} 4 <h3>這是訂單</h3> 5 {% endblock %}
1 from django.contrib import admin 2 from django.urls import path,re_path,include 3 from app01 import views 4 5 6 urlpatterns = [ 7 8 re_path(r'index/$',views.index), 9 re_path(r'order/$',views.order), 10 ]
1 from django.shortcuts import render,HttpResponse 2 3 def index(request): 4 5 return render(request,'index.html') 6 7 def order(request): 8 9 return render(request,'order.html')
而後咱們點擊訂單,就會跳到下面頁面
extends
標籤是這裏的關鍵。它告訴模版引擎,這個模版「繼承」了另外一個模版。當模版系統處理這個模版時,首先,它將定位父模版——在此例中,就是「base.html」。
那時,模版引擎將注意到 base.html
中的 block
標籤,並用子模版中的內容來替換這些block。
注意:
若是你在模版中使用 {% extends %}
標籤,它必須是模版中的第一個標籤。其餘的任何狀況下,模版繼承都將沒法工做。
在base模版中設置越多的 {% block %}
標籤越好。請記住,子模版沒必要定義所有父模版中的blocks,因此,你能夠在大多數blocks中填充合理的默認內容,而後,只定義你須要的那一個。多一點鉤子(block)總比少一點好。
若是你發現你本身在大量的模版中複製內容,那可能意味着你應該把內容移動到父模版中的一個 {% block %}
中。
If you need to get the content of the block from the parent template, the {{ block.super }}
variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using {{ block.super }}
will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.
爲了更好的可讀性,你也能夠給你的 {% endblock %}
標籤一個 名字 。例如:
1
2
3
|
{
%
block content
%
}
...
{
%
endblock content
%
}
|
在大型模版中,這個方法幫你清楚的看到哪個 {% block %}
標籤被關閉了。
block
標籤。
母版繼承一個子模板文件
(1)母版
<body> <h3>編輯書籍</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> {% include 'form.html' %} </div> </div> </div> </body>
(2)子模板form.html(所有數據)(不作任何處理)
<form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div class="form-group"> <label for="title">{{ field.label }}</label> {{ field }} <span>{{ field.errors.0 }}</span> </div> {% endfor %} <input type="submit" value="提交" class="btn btn-default pull-right"> </form>
這樣的效果就是母版把子模板數據加入到本身相應的位置
咱們先說下上面的子模板的缺點:
子模板中的數據有視圖提供,可是這是有問題的,若是同時有其餘文件繼承母版,那麼若是對應的視圖函數就必須得提供數據才行。這樣太麻煩,數據和模板脫離開了。
{% include 'form.html' %} #這個include是簡單地,只須要把form.html文件中的內容拿過來放到該位置就好了
步驟和自定義過濾器同樣:博客
from django.template import Library register = Library() @register.inclusion_tag("includ.html") def get_menu_style(): menu_list=[123,666,999] return {"menu_list":menu_list}
includ.html
<ul> {% for foo in menu_list %} <li>{{ foo }}</li> {% endfor %} </ul>
layout.html
{% load myfilters_tags %} #加載標籤文件 {% get_menu_style %} #模板語法
其實咱們寫的模板語法與瀏覽器一點關係都沒有。這其實都是後端解析數據,就是在render這個地方。其實render會把對應的模板文件讀出來。所有當作字符串。在字符串裏找到模板語法,把視圖函數中數據替換到相應位置。而後替換爲前端代碼
參考博文:Yuan 先生