Django(2)

2022-12-29 09:00:37

1.Django模板介紹

基礎概念

  • 模板是具有一定的格式或骨架,可以動態的生成HTML
  • 模板引擎決定以何種方式組織程式碼
  • 一個專案可以有一個或者是多個模板引擎,Django裡面主要兩個模板引擎:DTL、Jinja2。
  • Jinja2之前Flask筆記裡面有,點選跳轉https://www.cnblogs.com/gltou/p/16828437.html

 

DTL介紹

DTL是django原生的模板系統,Django1.8之前,Django框架只支援DTL。後面的版本可以相容多個模板引擎了。

 

模板的好處

  • 增強程式碼的可閱讀性
  • 增強程式碼的可維護性
  • 增加程式碼的可延伸性

 

關於DTL和Jinja2的區別以及誰更好,我簡單找了兩篇部落格,一個是闡述DTL優於Jinja2,一個是闡述Jinja2優於DTL的。箇中差異,如何選擇,因專案而議,因熟練而議。本文主要講解的是DTL的使用,下面的範例程式碼大家看的時候要注意。

 

2.Django模板相關設定

知識點

  • 掌握 settings.py中模板相關的設定
  • 瞭解 多個模板引擎支援情況下設定
  • 掌握 模板的載入順序

 

settings.py檔案templates屬性相關設定

引數說明

  • BACKEND:模板引擎設定,目前Django支援以下兩個模板引擎,即DTL和Jinja2
    • 預設是DTLdjango.template.backends.django.DjangoTemplates
    • 也可以設定成Jinja2django.template.backends.jinja2.Jinja2
  • DIRS:模板引擎按列表順序搜尋這些目錄以查詢模板原始檔。每種模板引擎後端都定義了一個慣用名稱作為應用內部存放模板的子目錄名稱。
    • DTL:templates目錄
    • Jinja2:jinja2目錄
  • APP_DIRS:決定模板引擎是否應該進入每個已安裝的應用(即模組)中查詢模板。改為True允許進入查詢時,還需要在settings.py檔案中將應用名稱(即模組名稱)追加到INSTALLED_APPS 屬性中。

  • OPTIONS:其他選項設定

 

如果需要同時支援兩種模板引擎,應該怎麼修改組態檔呢?

注意,組態檔新增好之後,要安裝jinja2,因為django沒有自帶jinja2

存在兩種模板引擎,兩個模板引擎對應的目錄下都有index.html,存取哪個呢?

模板檔案的查詢規則get_template('index.html'),根據TEMPLATES新增的模板引擎先後順序進行查詢。當遍歷完位置在第一個的模板引擎目錄以及已安裝應用(模組中)對應的目錄,找不到,才回去下一個設定的模板引擎中查詢對應的html檔案。實際工作專案中,當同時存在兩個模板引擎時,除了將模板HTML放到兩個引擎對應的目錄下面。在HTML模板檔案命名會以模板引擎不同做標記區分,避免同名檔案。

小結一下模板查詢的順序:按新增順序查詢,先根目錄後模組目錄

 

 

3.Django模板的使用

3.1.模板變數的使用

知識點

  • 掌握 模板語法
  • 掌握 Python中簡單資料型別的渲染
  • 掌握 Python中複雜資料型別的渲染
  • 掌握 DTL與Jinja2的使用區別

 

渲染Python中的變數

將變數以字典型別傳入到render函數中,模板通過{{變數名}}識別

渲染靜態圖片

疑問:我圖片明明是放在medias目錄裡面的,為什麼設定圖片路徑的時候是在media路徑下?

這個上一篇筆記裡面有講解,存取本地靜態檔案,我們設定的路由定址是在media路徑下開頭,任意結尾。通過正則匹配路徑,路徑沒有問題,就會到MEDIA_ROOT設定的目錄下去尋找對應的檔案

渲染Python中的物件

DTL與Jinja2的使用區別

  •  注意:變數名稱中不能有空格或標點符號
  • 下面的語法在DTL中不被支援
    •  {{ object["a.b"] }} 
    •  {{ object["a b"] }} 

 

  • 類中的成員方法呼叫不需要(),也不支援引數傳遞

 

 思考:Django模板引擎DTL的for迴圈和Jinja2有哪些不一樣呢?

 

3.2.模板標籤的使用

知識點

  • 瞭解 模板標籤的作用
  • 掌握 常用的模板標籤
  • 掌握 DTL和Jinja2的使用區別

 

模板標籤是什麼?

使用變數時有哪些不方便的地方:

  • list/tuple如果沒有迴圈標籤,肯定很難辦
  • 如果能加上if等條件判斷就好了
  • 頁面較多,如果能共用部分頁面就好了
  • ...........

 

模板標籤的使用

和Jinja2差不多,語法: {% tag %} ,有一些標籤有開始也需要有結束。

 

常用的模板標籤

主要有7類

  • 迴圈控制
  • 條件控制
  • 模板註釋
  • URL解析
  • with語句塊
  • 當前時間顯示
  • 繼承與包含(單獨作為一個點闡述)

 

3.2.1.迴圈控制

語法參考

迴圈內自帶的變數forloop

除了可以迴圈list和tuple,它還能迴圈dict

還支援重複迴圈(迴圈中再回圈),通過 cycle 實現

DTL的for迴圈與Jinja2的區別

  • 迴圈變數DTL中為forloop,Jinja2中為loop
  • 當list為空時:DTL通過 {% empty %} 處理,Jinja2中為 {% else %} 
  • 迴圈中的再回圈
    • DTL: {% cycle 'odd' 'even' %} 
    • Jinja2: {{ loop.cycle('odd','even') }} 
  • DTL不支援continue和break

 

範例程式碼

 

3.2.2.條件控制

語法參考

 

3.2.3.模板註釋

基本和Jinja2是一致的,{# 註釋 #}和{% comment %}的註釋檢視網頁原始碼是看不到的,而HTML的註釋<!--註釋-->通過網頁原始碼是可以看到的。

 

3.2.4.URL解析

URL標籤的使用:通過路由名稱逆向解析到對應的URL

static靜態檔案URL解析:

前置需知:首先在settings檔案中設定下STATIC_URL這個屬性,這個屬性的意思就是靜態檔案存取的url路徑,你改成什麼,存取的時候就存取什麼地址。新增STATICFILES_DIRS屬性,這個屬性就是你靜態檔案在專案下的路徑。

上述命令是如何存取到靜態檔案的呢?簡單講下:{% static "圖片名稱" %}這個命令會根據你設定的STATICFILES_DIRS的目錄,去這個目錄裡面查詢圖片。找到圖片後,再根據你設定的STATIC_URL,將圖片的URL傳遞給img便籤的src屬性。通過static標籤找到圖片後,需要通過{% load static %}對static進行解析展示。

DTL的URL解析與Jinja2的區別:

  • DTL:模板中使用 {% url 'url_name' params %} ,檢視中使用reverse()函數進行url解析
  • Jinja2: {{ url_for('index') }} 

 

3.2.5.with語句塊

這個基本上是和Jinja2是一樣的。實現塊級作用域,塊級裡面的變數和一些方法,只在with這個程式碼塊中有效果。

 

3.2.6.當前時間顯示

注意,圖示的時間表示是規定格式,大小寫代表不同的涵義不能亂改。詳見官方檔案:https://docs.djangoproject.com/en/3.0/ref/templates/builtins/

 

 

3.2.7.小結:DTL模板標籤和Jinja的使用區別

DTL與Jinja2大同小異,注意使用區別,主要集中在兩個地方:

  • 區別一:迴圈中的區別
  • 區別二:URL解析的區別

 

3.3.模板的繼承和包含

知識點

  • 瞭解 模板抽象和繼承的使用場景
  • 掌握 相關的幾個標籤
  • 掌握 DTL與Jinja2的使用區別

 

使用場景:

  • 每個頁面都參照了公共的頭部,js,css
  • 有幾個頁面結構和內容及其相似(如:導航選單)

 

3.3.1.模板的抽象和繼承

將模板差異化(個性化)的程式碼使用{% block  名稱 %}抽出來,使用{% extends %}繼承模板程式碼。接著使用{% block 可變名稱 %}對差異化程式碼重寫,不重寫,子模版會直接使用父模板的內容。如果想要複用差異化程式碼,使用{{ block.supper }}

注意:繼承父模板時,extends語句得放在最前面,不然沒有效果。

3.3.2.模板的包含

部分元件/功能/程式碼是大部分模板都需要用到的,怎麼做呢?將這部分內容單獨用一個html檔案存放,使用{% include %}呼叫。

3.4.模板過濾器

知識點

  • 瞭解 過濾器的作用
  • 掌握 過濾器的使用
  • 掌握 Django中常用的過濾器
  • 掌握 DTL與Jinja2的使用區別

 

過濾器的作用:對變數進行特殊處理後再進行渲染展示,比如將英語單詞轉換成大寫。

 

過濾器的語法

內建過濾器

日期/時間格式化選項傳送門

safe:將HTML轉成普通字串

如果傳遞過來的引數不是HTML格式的使用truncatechars擷取,如果是HTML格式的使用truncatechars_html擷取

備註:過濾器可以多個追加同時使用,方法和Jinja2一致,通過「 | 」追加對變數處理的過濾器

與Jinja2的區別

最大的區別就是過濾器的傳參,DTL通過冒好,Jinja2是括號

3.5.自定義過濾器

 知識點

  • 瞭解 自定義過濾器的使用場景
  • 掌握 Django中如何自定義過濾器
  • 瞭解 與Flask中自定義過濾器的區別

 

使用場景:Django自帶的過濾器不滿足我們的業務需求,對變數做較為複雜的處理,而後進行展示

 

自定義過濾器

新建的包只能叫這個名稱:templatetags,在模組的目錄下新建。新建的必須得是包,而不是資料夾,包可以被引入使用。編寫過濾器的檔名沒有強制要求

使用裝飾器註冊時,name不傳預設就是函數的名稱

注意事項:

  • 新增自定義過濾器後記得重啟開發伺服器
  • 自定義過濾器所在的模組需要新增到settings.py中的INSTALLED_APPS內

範例