django-模板之標簽

来源:https://www.cnblogs.com/wby-110/archive/2020/07/23/13368910.html
-Advertisement-
Play Games

模板 模版是純文本文件,可以生成任何基於文本的文件格式,比如HTML,XML,CSV等。Django模版語言致力於在性能和簡單性上取得平衡。Django的模版系統並不是簡單的將Python嵌入到HTML中。 下麵是一個小模版,它展示了一些基本的元素。 {% extends "base_generic ...


模板

模版是純文本文件,可以生成任何基於文本的文件格式,比如HTML,XML,CSV等。Django模版語言致力於在性能和簡單性上取得平衡。Django的模版系統並不是簡單的將Python嵌入到HTML中。

下麵是一個小模版,它展示了一些基本的元素。

{% extends "base_generic.html" %}

{% block title %}{{ section.title }}{% endblock %}

{% block content %}
<h1>{{ section.title }}</h1>

{% for story in story_list %}
<h2>
  <a href="{{ story.get_absolute_url }}">
    {{ story.headline|upper }}
  </a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}

註意:
    調用對象裡面的方法的時候,不需要寫括弧來執行,並且只能執行不需要傳參數的方法,如果你的這個方法需要傳參數,那麼模板語言不支持,不能幫你渲染

每一個Web框架都需要一種很便利的方法用於動態生成HTML頁面。 最常見的做法是使用模板。模板包含所需HTML頁面的靜態部分,以及一些特殊的模版語法,用於將動態內容插入靜態部分。

Django可以配置一個或多個模板引擎(語言),也可以不用引擎。Django自帶一個稱為DTL(Django Template Language )的模板語言,以及另外一種流行的Jinja2語言(需要安裝,pip install Jinja2)。

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

語法
變數相關的用{{}},邏輯相關的用{%%}。

模板渲染的官方文檔:(https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#std:templatetag-for)

本文參考官方文檔,即用的是DTL引擎。

Django模板語言的語法包括四種結構:變數、標簽、過濾器、註釋。

變數

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

在Django的模板語言中按此語法使用:{{ 變數名 }}。當模版引擎遇到一個變數,它將從上下文context中獲取這個變數的值,然後用值替換掉它本身。 變數的命名包括任何字母數字以及下劃線的組合。變數名稱中不能有空格或標點符號。

深度查詢據點符(.)在模板語言中有特殊的含義。當模版系統遇到點("."),它將以這樣的順序查詢:

  1. 字典查詢(Dictionary lookup),字典鍵查找優先於方法查找
  2. 屬性或方法查詢(Attribute or method lookup)
  3. 數字索引查詢(Numeric index lookup)

註意事項:

  1. 如果計算結果的值是可調用的,它將被無參數的調用。 調用的結果將成為模版的值。
  2. 如果使用的變數不存在, 模版系統將插入 string_if_invalid 選項的值, 它被預設設置為'' (空字元串) 。
  3. {{ foo.bar }}這種模版表達式中的“bar”,如果在模版上下文中存在,將解釋為一個字面意義的字元串而不是使用變數bar的值 。

標簽

模版語言中的標簽類似Python中的函數,可以輸出內容、控制結構,甚至可以訪問其他的模板標簽。

{% csrf_token %} # csrf令牌標簽,用於POST提交。

部分標簽需要使用起始和閉合標簽。 

for迴圈標簽

迴圈對象中每個元素。需要結束標簽{% endfor %}

顯示athlete_list中提供的運動員列表:
<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>

迴圈對象points的每個元素都是(x,y)這樣的二元元組,並返回:
{% for x, y in points %}
    There is a point at {{ x }},{{ y }}
{% endfor %}

訪問一個字典中的鍵值:
{% for key, value in data.items %}
    {{ key }}: {{ value }}
{% endfor %}

可以使用{% for obj in list reversed %}進行反向迴圈。

下麵是Django為for標簽內置的一些屬性,可以當作變數一樣使用{{ }}在模版中使用。

forloop.counter:迴圈的當前索引值,從1開始計數;常用於生成一個表格或者列表的序號

forloop.counter0:迴圈的當前索引值,從0開始計數;

forloop.revcounter: 當前迴圈的倒序索引值(最後一個為1

forloop.revcounter0  當前迴圈的倒序索引值(最後一個為0

forloop.first:判斷當前是否迴圈的第一次,是的話,該變數的值為True

forloop.last:如果這是最後一次迴圈,則為真

forloop.parentloop:對於嵌套迴圈,返回父迴圈所在的迴圈次數。

for … empty

for標簽帶有一個可選的{% empty %}從句,以便在迴圈對象是空的或者沒有被找到時,可以有所操作和提示。

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% empty %}      # 若列表為空,則執行。
    <li>Sorry, no athletes in this list.</li>
{% endfor %}
</ul>

if-elif-else標簽

需要{% endif %}結束標簽。

{% if athlete_list %}
    Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
    Athletes should be out of the locker room soon!
{% else %}
    No athletes.
{% endif %}

還可以在if標簽支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷等多種運算符,註意條件兩邊都有空格。也可使用過濾器。

{% if somevar == "x" %}
  This appears if variable somevar equals the string "x"
{% endif %}

{% if athlete_list|length > 1 %}
   Team: {% for athlete in athlete_list %} ... {% endfor %}
{% else %}
   Athlete: {{ athlete_list.0.name }}
{% endif %}

# 註意,大多數模版過濾器都返回字元串類型,所以使用過濾器做整數類型的比較通常是錯誤的,但length是一個例外。

操作符都可以組合以形成複雜表達式。操作符的優先順序從低至高如下:

or
and
not
in
==,!=,<,>,<= ,>=
與Python的規則是一樣的。

如果想要不同的優先順序,那麼需要使用嵌套的if標簽,而不能使用圓括弧。比較運算符不能像Python或數學符號中那樣“鏈接”。

{% if a > b > c %}  (錯誤的用法)
{% if a > b and b > c %} (正確的用法)

{% if athlete_list and coach_list %}
    Both athletes and coaches are available.
{% endif %}

{% if not athlete_list %}
    There are no athletes.
{% endif %}

{% if athlete_list or coach_list %}
    There are some athletes or some coaches.
{% endif %}

{% if not athlete_list or coach_list %}
    There are no athletes or there are some coaches.
{% endif %}

{% if athlete_list and not coach_list %}
    There are some athletes and absolutely no coaches.
{% endif %}

with

使用一個簡單地名字緩存一個複雜的變數,多用於給一個複雜的變數起別名。當需要使用一個代價較大的方法(比如訪問資料庫)很多次的時候這是非常有用的。

像這樣:

{% with total=business.employees.count %}
    {{ total }} <!--只能在with語句體內用-->
{% endwith %}
或:
{% with business.employees.count as total %}
    {{ total }}
{% endwith %}

可以分配多個變數:

{% with alpha=1 beta=2 %}
    ...
{% endwith %}

註意等號左右不要加空格

csrf_token

若不使用此標簽以post方式提交表單時,會報錯。如果在settings裡面的中間件配置里把csrf的防禦機制給註銷,則不會報錯,但不安全。這個標簽用於跨站請求偽造保護

在頁面的form表單裡面任何位置寫上{% csrf_token %},在模板渲染的時將被替換成類似於下方的input標簽:
<input type="hidden" name="csrfmiddlewaretoken" value="8J4z1wiUEXt0gJSN59dLMnktrXFW0hv7m4d40Mtl37D7vJZfrxLir9L3jSTDjtG8">

這個標簽的值是個隨機字元串,提交的時候,值也被提交了,首先這個標簽是後端渲染給頁面加上的,那麼當通過form表單提交數據時候,後臺django有相同的一個值,可以做對應驗證是不是我給你的token,如果用戶沒有按照這個正常的頁面來post提交表單數據,那麼就能知道這個請求是非法的,反爬蟲或者惡意攻擊網站

comment

註釋

註釋可以包含任何模版內的代碼,有效的或者無效的都可以。當要註釋掉一些代碼時,可以用此來記錄代碼被註釋掉的原因。單行註釋語法:{# #}

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

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

{% comment %}{% endcomment %}之間的內容會被忽略,作為註釋。例如:

<p>Rendered text with {{ pub_date|date:"c" }}</p>
{% comment "Optional note" %}
    <p>Commented out text with {{ create_date|date:"c" }}</p>
{% endcomment %}

comment標簽不能嵌套使用。

block和extends標簽

繼承和覆寫模版。類似Python的類繼承和重寫機制。

extends標簽表示當前模板繼承自一個父模板。

這個標簽可以有兩種用法:

  • {% extends "base.html" %}:繼承名為"base.html"的父模板
  • {% extends variable %}:使用variable變數表示的模版
模板繼承

Django模版引擎中最強大也是最複雜的部分就是模版繼承了。模版繼承允許你創建一個包含基本“骨架”的父親模版,它包含站點中的共有元素,並且可以定義能夠被子模版覆蓋的blocks。通過下麵這個例子,理解模版繼承的概念:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}My amazing site{% endblock %}
    </title>#註意此處,block標簽。
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}   #註意此處
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}         #結束標簽
    </div>

    <div id="content">
        {% block content %}
        {% endblock %}      #註意此處
    </div>
</body>
</html>

這個模版,通常被命名為base.html,它定義了一個可以用於兩列排版頁面的簡單HTML骨架。

“子模版”需要做的是先繼承父模板base.html,然後覆寫、填充,或者說實現其中的blocks

block是在子模版中可能會被覆蓋掉的位置。在上面的例子中,block標簽定義了三個可以被子模版內容填充的block,分別是title、content和siderbar。

子模版可能看起來是這樣的:

{% extends "base.html" %}        #extends標簽是這裡的關鍵。它告訴模版引擎,這個模版“繼承”了另一個模版。當模版系統處理這個模版時,首先會去載入父模版,也就是“base.html”。

{% block title %}My blog{% endblock %}   #修改base里title標簽里的內容。

{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

# 載入過程中,模版引擎將註意到base.html中的三個block標簽,並用子模版中的內容來替換這些block。

請註意,上面例子中的子模版並沒有定義sidebar block,這種情況下,將使用父模版中的內容。父模版的{% block %}標簽中的內容總是被用作預設內容。

Django多級繼承常用方式類似下麵的三級結構:

  • 創建一個base.html模版,用來控制整個站點的主要視覺和體驗。
  • 為站點的每一個app,創建一個base_SECTIONNAME.html模版。 例如base_news.html,base_sports.html。這些模版都繼承base.html,並且包含了各自特有的樣式和設計。
  • 為每一個頁面類型,創建獨立的模版,例如新聞內容或者博客文章。 這些模版繼承對應app的模版。

上面的方式可以使代碼得到最大程度的復用,並且使得添加內容到共用的內容區域更加簡單,例如app範圍內的導航條。

使用繼承的一些相關說明:

  • 如果在模版中使用{% extends %}標簽,它必須是模版中的第一個標簽,必須放在文件首行

  • 在base模版中設置越多的{% block %}標簽越好。子模版不必定義全部父模版中的blocks,所以可以在大多數blocks中填充合理的預設內容,然後,只定義你需要的那一個。多一點鉤子總比少一點好。

  • 如果發現自己在複製大量重覆的模版內容,那意味著應該把重覆的內容移動到父模版中的一個{% block %}中。

  • 如果需要獲取父模板中的block的內容,想要在父block中新增內容而不是完全覆蓋它,可以使用{{ block.super }}變數。使用{{ block.super }} 插入的數據不會被自動轉義,因為父模板中的內容已經被轉義。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 本篇文章收錄於專輯:http://dwz.win/HjK,點擊解鎖更多數據結構與演算法的知識。 你好,我是彤哥,一個每天爬二十六層樓還不忘讀源碼的硬核男人。 上一節,我們從最壞、平均、最好三種情況分析了演算法的複雜度,得出結論,通常來說,使用最壞情況來評估演算法的複雜度完全夠用了。 但是,有些演算法是 ...
  • 《Microsoft .NET 企業級應用架構設計》 [作者] (意) Dino Esposito (意) Andrea Saltarello[譯者] (中) 陳黎夫[出版] 人民郵電出版社[版次] 2010年06月 第1版[印次] 2010年06月 第1次 印刷[定價] 69.00元 【前言】 ( ...
  • GitHub(國內)加速 Windows的加速方式 大家知道GitHub這個網站,但是由於GitHub是國外的網站,國外伺服器等諸多原因導致國內訪問GitHub非常慢(其實最主要的原因是GitHub的分發加速網路的功能變數名稱遭到dns污染),clone、push、pull倉庫有時只有幾KB的速度,而且動不 ...
  • 數據結構--哈希表(Java) 博客說明 文章所涉及的資料來自互聯網整理和個人總結,意在於個人學習和經驗彙總,如有什麼地方侵權,請聯繫本人刪除,謝謝! 介紹 哈希表底層是數組加鏈表或者是數組加二叉樹,一個數組裡面有多個鏈表,通過散列函數來提高效率 代碼 package cn.guizimo.hash ...
  • 今天不知咋回事使用easywechat的內容安全api,不知咋回事.之前還可以使用的這些天突然報這個錯,也不知道是不是因為升級還是與其他的衝突, 那怎麼辦呢,還是用下原生的介面,在這裡我獲取的token方法還是easywechat的方式 $miniProgram = ZFac::miniProgra ...
  • 查找--斐波那契查找(Java) 博客說明 文章所涉及的資料來自互聯網整理和個人總結,意在於個人學習和經驗彙總,如有什麼地方侵權,請聯繫本人刪除,謝謝! 介紹 黃金分割點是指把一條線段分割為兩部分,使其中一部分與全長之比等於另一部分與這部分之比。取其前三位數字的近似值是0.618。 斐波那契數列 { ...
  • 功能需求: 一、獲取本地音頻文件,進行解析成二進位數據音頻流 二、將音頻流轉化成byte[]數組,按指定大小位元組數進行分包 三、將音頻流分成若幹個包,以List列表形式緩存到redis資料庫中 四、從redis資料庫中獲取數據,轉換成音頻流輸出到瀏覽器播放、實現音頻下載功能 程式如下: 1.在Spr ...
  • 一、jQuery初體驗 使用jQuery給一個按鈕綁定單擊事件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...