在 Jinja2 中,循環和條件被稱為控制結構,因為它們會影響程序的流程。 {% 控制結構使用由和 %} 字符包圍的塊。
我們首先要看的結構是循環。
Jinja2 作為壹種模板語言不需要廣泛的循環類型選擇,所以我們只得到 for 循環。
For 循環以 開頭 {% for my_item in my_collection %} 和結尾 {% endfor %} 。這與您在 Python 中循環叠代的方式非常相似。
這 my_item 是壹個循環變量,它將在我們遍歷元素時獲取值。並且 my_collection 是持有對叠代集合的引用的變量的名稱。
在循環體內部,我們可以 my_item 在其他控制結構中使用變量,比如 if 條件,或者簡單地使用 {{ my_item }} 語句顯示它。
好的,但是妳會在哪裏使用妳問的循環?在您的模板中使用單個變量在大多數情況下都可以正常工作,但您可能會發現引入層次結構和循環將有助於抽象您的數據模型。
例如,前綴列表或 ACL 由許多行組成。將這些行表示為單個變量是沒有意義的。
最初,您可以使用每行壹個變量對特定前綴列表進行建模,如下所示:
可以在以下模板中使用:
渲染結果:
這種方法雖然有效,但也存在壹些問題。
如果我們想在前綴列表中有更多行,我們必須創建另壹個變量,然後再創建壹個,以此類推。我們不僅必須將這些新項目添加到我們的數據結構中,模板還必須單獨包含所有這些新變量。這是不可維護的,消耗大量時間並且很容易出錯。
有壹個更好的方法,考慮下面的數據結構:
以及模板渲染前綴列表配置:
渲染後:
如果您仔細觀察,您會發現這本質上是對同壹事物進行建模,即帶有多個條目的前綴列表。但是通過使用列表,我們清楚地說明了我們的意圖。即使在視覺上,您也可以立即看出所有縮進的行都屬於 PL_AS_65003_IN。
在這裏添加前綴列表很簡單,我們只需要在塊中添加壹個新行。此外,我們的模板根本不需要更改。如果我們使用循環來叠代,就像我們在這裏所做的那樣,遍歷這個列表,那麽如果我們重新運行渲染,新的行將被拾取。小小的改變,但讓事情變得容易多了。
您可能已經註意到這裏仍有改進的空間。前綴列表的名稱在前綴列表定義和我們的 for 循環中是硬編碼的。不要害怕,這是我們很快會改進的。
現在讓我們看看如何遍歷字典。我們將再次使用 for 循環構造,記住,這就是我們所擁有的!
我們可以使用與叠代列表元素相同的語法,但這裏我們將叠代字典鍵。要檢索分配給鍵的值,我們需要使用下標,即 [] 符號。
使用字典而不是列表的壹個優點是我們可以使用元素的名稱作為參考,這使得檢索對象及其值變得更加容易。
假設我們使用 list 來表示我們的接口集合:
沒有簡單的方法來檢索 Ethernet2 條目。我們要麽必須遍歷所有元素並進行鍵名比較,要麽必須求助於高級過濾器。
需要註意的壹件事(希望這壹點越來越明顯)是我們需要花壹些時間對數據進行建模,以便於使用。這是您在第壹次嘗試時很少會做對的事情,所以不要害怕嘗試和叠代。
按照我們的示例,我們可以將數據保存在分配給 interfaces 字典中鍵的各個接口上,而不是將它們放在列表中:
現在我們可以像這樣在模板中訪問這些數據:
給我們最終結果:
這裏 intf 指的是 Ethernet1 和 Ethernet2 鍵。要訪問每個接口的屬性,我們需要使用 interfaces[intf] 符號。
還有另壹種叠代字典的方法,我個人更喜歡。 items() 我們可以通過使用方法同時檢索鍵和它的值。
最終結果是相同的,但通過使用 items() 方法,我們簡化了對屬性的訪問。如果您想遞歸地叠代深度嵌套的字典,這壹點就變得尤為重要。
我還承諾展示如何改進前綴列表示例,這就是它的 items() 用武之地。
我們通過使每個前綴列表名稱成為字典中的鍵來對我們的數據結構進行小修改 prefix_lists
我們現在添加外循環叠代字典中的鍵值對:
渲染給我們同樣的結果:
在這裏,不再有對前綴列表名稱的硬編碼引用!如果您需要另壹個前綴列表,您只需將其添加到字典中,它就會被我們的循環 prefix_lists 自動拾取。 for
註意: 如果您使用的是 Python < 3.6 的版本,則不訂購字典。這意味著您記錄數據的順序可能與模板內處理項目的順序不同。
如果您依賴於它們被記錄的順序,您應該 collections.OrderedDict 在 Python 腳本中使用 Jinja2 時使用,或者您可以 dictsort 在模板中應用過濾器以按鍵或值對字典進行排序。
按鍵排序:
按值排序:
這就結束了 Jinja2 模板中循環的基礎知識。上述用例應滿足您 95% 的需求。
如果您正在尋找與循環相關的壹些高級功能的討論,請放心,我也會寫這些內容。我決定在本教程的最後幾章留下更深入的 Jinja2 主題,並專註於讓您更快地提高工作效率的核心內容。
現在我們已經完成了循環,是時候繼續討論條件了。
Jinja2 實現了壹種條件語句,即 if 語句。對於分支,我們可以使用 elif and else 。
Jinja2 中的條件可以以幾種不同的方式使用。現在,我們將看看壹些用例以及它們如何與其他語言特性相結合。
我們首先要看的是將值與條件進行比較,這些使用 ==, !=, >, >=,