模版層Template layer

每個Web框架都須要一種很便利的方法用於動態生成HTML頁面。 最多見的作法是使用模板。html

模板包含所需HTML頁面的靜態部分,以及一些特殊的模版語法,用於將動態內容插入靜態部分。web

說白了,模板層就是如何往HTML文件中填入動態內容的系統。django

Django能夠配置一個或多個模板引擎(語言),也能夠不用引擎。後端

Django自帶一個稱爲DTL(Django Template Language )的模板語言,以及另一種流行的Jinja2語言(須要提早安裝,pip install Jinja2)。框架

Django爲加載和渲染模板定義了一套標準的API,與具體的後臺無關。加載指的是,根據給定的模版名稱找到的模板而後預處理,一般會將它編譯好放在內存中。渲染則表示,使用Context數據對模板插值並返回生成的字符串。函數

DTL做爲Django原生的模板系統,一直到Django1.8,都是惟一的內置模版系統,可能你對它有些意見,可是它仍然是一個優秀的模版庫。若是沒有特別重要的理由,須要選擇另一種模版系統的話,建議堅持使用DTL,特別是在編寫可插拔的應用並打算髮布其模板的時候。Django不少內部組件都使用了DTL,例如django.contrib.admin,若是你不想讓它們罷工,或者花費大力氣進行修改,不要放棄DTL。post

1、 配置引擎

模板引擎經過settings中的TEMPLATES設置來配置。這是一個列表,與引擎一一對應,每一個元素都是一個引擎配置字典。由startproject命令生成的settings.py會自定定義以下的值:ui

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            # ... some options here ...
        },
    },
]

BACKEND:後端。內置的後端有django.template.backends.django.DjangoTemplatesdjango.template.backends.jinja2.Jinja2this

OPTIONS中包含了具體的後端設置。編碼

因爲絕大多數引擎都是從文件加載模板的,因此每種模板引擎都包含兩項通用設置:

  • DIRS:定義了一個目錄列表,模板引擎按列表順序搜索這些目錄以查找模板源文件。
  • APP_DIRS:告訴模板引擎是否應該進入每一個已安裝的應用中查找模板。一般請將該選項保持爲True。

每種模板引擎後端都定義了一個慣用的名稱做爲應用內部存放模板的子目錄名稱。(例如Django爲它本身的模板引擎指定的是 ‘templates’,爲jinja2指定的名字是‘jinja2’)。尤爲是,django容許你有多個模板引擎後端實例,且每一個實例有不一樣的配置選項。 在這種狀況下你必須爲每一個配置指定一個惟一的NAME .

DTL引擎的OPTIONS配置項中接受如下參數:

  • 'autoescape':一個布爾值,用於控制是否啓用HTML自動轉義功能。默認爲True。
  • context_processors: 以"."爲分隔符的Python調用路徑的列表。默認是個空列表。
  • 'debug':打開/關閉模板調試模式的布爾值。默認和setting中的DEBUG有相同的值。
  • 'loaders':模板加載器類的虛擬Python路徑列表。默認值取決於DIRS和APP_DIRS的值。
  • string_if_invalid:非法變量時輸出的字符串。默認爲空字符串。
  • file_charset:用於讀取磁盤上的模板文件的字符集編碼。默認爲FILE_CHARSET的值。
  • 'libraries':用於註冊模板引擎。 這能夠用於添加新的庫或爲現有庫添加備用標籤。
  • 'builtins':以圓點分隔的Python路徑的列表。

2、 簡單的用法

django.template.loader中定義了兩個函數以加載模板。

get_template(template_name,using = None)[source]

該函數使用給定的名稱查找和加載模板,並返回一個Template對象。

模板的查找和加載機制取決於每種後端引擎和配置,若是想使用指定的模板引擎進行查找,請將模板引擎的NAME賦給get_template的using參數。

select_template(template_name_list,using = None)[source]

和get_template()類似, 只不過它使用包含模板名稱的列表做爲參數。

select_template()get_template()返回的Template對象都必須提供一個render()方法,以下所示:

Template.render(context=None, request=None)

經過給定的context對該模板進行渲染。

若是提供了context,那麼它必須是一個dict對象。若是要提供request參數 ,必須使用HttpRequest對象。

針對下面的TEMPLATES配置,對模版文件的搜索順序和路徑以下:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            '/home/html/example.com',
            '/home/html/default',
        ],
    },
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [
            '/home/html/jinja2',
        ],
    },
]

若是你調用函數get_template('story_detail.html'), Django將按如下順序查找story_detail.html

/home/html/example.com/story_detail.html('django'引擎)
/home/html/default/story_detail.html('django'引擎)
/home/html/jinja2/story_detail.html('jinja2'引擎)

若是你調用函數select_template(['story_253_detail.html','story_detail.html']),Django按如下順序查找:

/home/html/example.com/story_253_detail.html('django'引擎)
/home/html/default/story_253_detail.html('django'引擎)
/home/html/jinja2/story_253_detail.html('jinja2'引擎)
/home/html/example.com/story_detail.html('django'引擎)
/home/html/default/story_detail.html('django'引擎)
/home/html/jinja2/story_detail.html('jinja2'引擎)

注意:Django查找到任何一個匹配的模板後便中止搜尋,因此這是個相似url搜索的短路操做!

強調:前面咱們介紹過,建議在每一個APP的的模版子目錄下都創建一個子目錄來惟一對應這個APP。這樣作能夠加強你的APP的可用性。 將全部的模版文件放在根模版目錄下會引起混淆。

要在一個子目錄內加載模板,像下面這樣:

get_template('news/story_detail.html')

若是結合上面例子中的TEMPLATES配置,這將會嘗試按順序查找並加載下列模板︰

/home/html/example.com/news/story_detail.html('django'引擎)
/home/html/default/news/story_detail.html('django'引擎)
/home/html/jinja2/news/story_detail.html('jinja2'引擎)

另外,爲了減小加載模板、渲染模板等重複工做,django提供了處理這些工做的快捷函數。

render_to_string(template_name, context=None, request=None, using=None)[source]

render_to_string()會像get_template()同樣加載模板並當即調用render()方法。 它須要如下參數。

  • TEMPLATE_NAME:要加載的模板的名稱或列表。
  • context:要用做模板的上下文進行渲染的數據字典,也就是你要插入的動態數據字典。
  • request:可選的HttpRequest對象。
  • using:指定使用的模板引擎NAME。 搜索模板將僅限於該引擎。

用法示例:

from django.template.loader import render_to_string rendered = render_to_string('my_template.html', {'foo': 'bar'}) 

3、基本語法

之後,若是沒有特別強調,都是針對DTL引擎。

Django模板語言的語法包括四種結構。

1. 變量

變量的值來自context中的數據字典, 相似於字典對象的keys到values的映射關係。

變量是被}}{{括起來的部分,例如:

My first name is {{ first_name }}. My last name is {{ last_name }}. 

假若有一個上下文{'first_name': 'John', 'last_name': 'Doe'},模板渲染後的真實值爲:

My first name is John. My last name is Doe.

字典查詢,屬性查詢和列表索引查找都是經過圓點符號.來實現。因此圓點在模版引擎中是萬能的上帝,不知道該怎麼寫下去的時候,就嘗試點點點....:

{{ my_dict.key }} {{ my_object.attribute }} {{ my_list.0 }}

2. 標籤

模版語言中的標籤相似Python中的函數,功能多樣,使用靈活。能夠輸出內容、控制結構,甚至能夠訪問其餘的模板標籤。

標籤是由%}{%來定義的,例如:

{% csrf_token %} # csrf令牌標籤

大部分標籤都接受參數:

{% cycle 'odd' 'even' %} # 循環使用'odd'和'even'

部分標籤須要使用起始和閉合標籤,典型表明爲for循環標籤和if判斷標籤:

{% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %}

3. 過濾器

過濾器用於修改變量或標籤參數的值。例以下面這樣:

{{ django|title }}

若是有一個上下文{'django': 'the web framework for perfectionists with deadlines'},那麼模板最終呈現:

The Web Framework For Perfectionists With Deadlines # 全部的單詞首字母大寫了

有些過濾器還接收一個參數:

{{ my_date|date:"Y-m-d" }} # 按指定的格式"Y-m-d",顯示日期 

4. 註釋

模版語言的註釋看起來像這樣:

{# this won't be rendered #} # 單行註釋

{% comment %}標籤提供多行註釋功能。

詳細教程

Django模板語言詳解

Django內置模板標籤

Django內置模版過濾器

django特殊的標籤和過濾器

django人類可讀性

django自定義模板標籤和過濾器

相關文章
相關標籤/搜索