模板
模版是純文本檔案,可以生成任何基于文本的檔案格式,比如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=https://www.cnblogs.com/wby-110/p/"{{ 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中獲取這個變數的值,然后用值替換掉它本身, 變數的命名包括任何字母數字以及下劃線的組合,變數名稱中不能有空格或標點符號,
深度查詢據點符(.)在模板語言中有特殊的含義,當模版系統遇到點("."),它將以這樣的順序查詢:
- 字典查詢(Dictionary lookup),字典鍵查找優先于方法查找,
- 屬性或方法查詢(Attribute or method lookup)
- 數字索引查詢(Numeric index lookup)
注意事項:
- 如果計算結果的值是可呼叫的,它將被無引數的呼叫, 呼叫的結果將成為模版的值,
- 如果使用的變數不存在, 模版系統將插入 string_if_invalid 選項的值, 它被默認設定為'' (空字串) ,
- 像
{{ 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=https://www.cnblogs.com/wby-110/p/"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=https://www.cnblogs.com/wby-110/p/"style.css" />
<title>{% block title %}My amazing site{% endblock %}
</title>#注意此處,block標簽,
</head>
<body>
<div id="sidebar">
{% block sidebar %} #注意此處
<ul>
<li><a href=https://www.cnblogs.com/wby-110/p/"/">Home</a></li>
<li><a href=https://www.cnblogs.com/wby-110/p/"/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 }}插入的資料不會被自動轉義,因為父模板中的內容已經被轉義,在
{% block %}之外創建的變數使用模板標簽的as語法,不能在塊內使用,例如,下面的模板不會顯示任何內容:
{% trans "Title" as title %}
{% block content %}{{ title }}{% endblock %}
為了更好的可讀性,可以給
{% endblock %}標簽一個取名字,如:{% block content %},在大型模版中,這有助于你清楚的看到哪一個{% block %}標簽被關閉了,不能在一個模版中定義多個相同名字的block標簽,
Django1.10中添加了使用相對路徑的能力,通常模板名稱是相對于模板加載器的根目錄,字串引數也可以是以./或../開頭的相對路徑, 例如,假設有以下目錄結構:
dir1/
template.html
base2.html
my/
base3.html
base1.html
在template.html中,以下路徑將有效:
{% extends "./base2.html" %}
{% extends "../base1.html" %}
{% extends "./my/base3.html" %}
url
于url的反向決議,回傳與給定視圖和可選引數匹配的絕對路徑參考(不帶域名的URL),在決議后回傳的結果路徑字串中,每個特殊字符將使用iri_to_uri()編碼,這可以避免在模板中硬編碼超級鏈接路徑,
{% url 'some-url-name' v1 v2 %}
第一個引數是url()的名字, 它可以是一個被引號引起來的字串或者其他的背景關系變數,其他引數是可選的并且以空格隔開,這些值會在URL中以引數的形式傳遞,上面的例子展示了如何傳遞位置引數,也可以使用關鍵字引數,
{% url 'some-url-name' arg1=v1 arg2=v2 %}
不要把位置引數和關鍵字引數混在一起使用,URLconf所需的所有引數都應該提供,
例如,假設有一個視圖app_views.client,其URLconf接受客戶端ID,并如下所示:
('^client/([0-9]+)/$', app_views.client, name='app-views-client')
如果你的應用中的URLconf已經被包含到專案URLconf中,比如下面這樣
('^clients/', include('project_name.app_name.urls'))
然后,在模板中,你可以創建一個此視圖的鏈接,如下所示:
{% url 'app-views-client' client.id %}
模板標簽會輸出字串:/clients/client/123/
如果希望在不顯示網址的情況下檢索網址,可以使用略有不同的呼叫:
{% url 'some-url-name' arg arg2 as the_url %}
<a href=https://www.cnblogs.com/wby-110/p/"{{ the_url }}">I'm linking to {{ the_url }}</a>
如果視圖不存在,{% url ... as var %}語法不會導致錯誤,
{% url 'some-url-name' as the_url %}
{% if the_url %}
<a href=https://www.cnblogs.com/wby-110/p/"{{ the_url }}">Link to optional stuff</a>
{% endif %}
如果使用urlconf的名稱空間網址,通過冒號指定完全名稱,如下所示:
{% url 'myapp:view-name' %}
include
組件
加載指定的模板并以標簽內的引數渲染,這是一種引入別的模板的方法,要將include和extend區分開,include類似Python的import,
{% include "foo/bar.html" %}
也可以使用變數名:
{% include template_name %}
下面這個示例生成輸出“Hello, John!”:
context:變數greeting="Hello",變數person="John",
模板:
{% include "name_snippet.html" %}
name_snippet.html模板:
{{ greeting }}, {{ person|default:"friend" }}!
可以使用關鍵字引數將額外的背景關系傳遞到模板:
{% include "name_snippet.html" with person="Jane" greeting="Hello" %}
如果僅使用提供的變數來渲染背景關系,添加only選項,
{% include "name_snippet.html" with greeting="Hi" only %}
將子模版渲染并嵌入當前HTML中的變種方法,不是決議子模版并在被父模版包含的情況下展現其被父模版定義的內容,這意味著在不同的被包含的子模版之間并不共享父模版的狀態,每一個子模板包含都是完全獨立的渲染程序,
load
加載自定義模板標簽,
下面的模板將會從somelibrary和package包中的otherlibrary中載入所有已經注冊的標簽和過濾器,
{% load somelibrary package.otherlibrary %}
還可以使用from引數從庫中選擇性加載單個過濾器或標記,
{% load foo bar from somelibrary %}
Django內置標簽總覽
可以查詢下表來總覽Django的內置標簽:
| 標簽 | 說明 |
|---|---|
| autoescape | 自動轉義開關 |
| block | 塊參考 |
| comment | 注釋 |
| csrf_token | CSRF令牌 |
| cycle | 回圈物件的值 |
| debug | 除錯模式 |
| extends | 繼承模版 |
| filter | 過濾功能 |
| firstof | 輸出第一個不為False的引數 |
| for | 回圈物件 |
| for … empty | 帶empty說明的回圈 |
| if | 條件判斷 |
| ifequal | 如果等于 |
| ifnotequal | 如果不等于 |
| ifchanged | 如果有變化,則.. |
| include | 匯入子模版的內容 |
| load | 加載標簽和過濾器 |
| lorem | 生成無用的廢話 |
| now | 當前時間 |
| regroup | 根據物件重組集合 |
| resetcycle | 重置回圈 |
| spaceless | 去除空白 |
| templatetag | 轉義模版標簽符號 |
| url | 獲取url字串 |
| verbatim | 禁用模版引擎 |
| widthratio | 寬度比例 |
| with | 背景關系變數管理器 |
autoescape
控制自動轉義是否可用,引數是on或off, 該標簽會以一個endautoescape作為結束標簽.
例如:
{% autoescape on %}
{{ body }}
{% endautoescape %}
cycle
每當這個標簽被訪問,回傳它的下一個元素,第一次訪問回傳第一個元素,第二次訪問回傳第二個引數,以此類推. 一旦所有的變數都被訪問過了,就會回到最開始的地方,重復下去,在回圈中特別有用:
{% for o in some_list %}
<tr class="{% cycle 'row1' 'row2'%}">
...
</tr>
{% endfor %}
cycle的本質是根據某個規律,提供某種特性,比如想回圈給表格的行添加底色等等,
也可以使用變數, 例如,有兩個模版變數:rowvalue1和rowvalue2, 可以讓他們的值像這樣替換:
{% for o in some_list %}
<tr class="{% cycle rowvalue1 rowvalue2 %}">
...
</tr>
{% endfor %}
被包含在cycle中的變數將會被轉義, 可以禁止自動轉義:
{% for o in some_list %}
<tr class="{% autoescape off %}{% cycle rowvalue1 rowvalue2 %}{% endautoescape %}">
...
</tr>
{% endfor %}
可以混合使用變數和字串:
{% for o in some_list %}
<tr class="{% cycle 'row1' rowvalue2 'row3' %}">
...
</tr>
{% endfor %}
在某些情況下,可能需要連續參考一個當前回圈的值,而不前進到下一個回圈值,要達到這個目的,只需使用as來給{% cycle %}取一個別名,就像這樣:
{% cycle 'row1' 'row2' as rowcolors %}
設定別名后,就可以將別名當作一個模板變數進行參考,從而隨意在模板中插入當前回圈的值, 如果要將回圈值移動到原始cycle標記的下一個值,可以使用另一個cycle標記并指定變數的名稱,看下面的例子:
<tr>
<td class="{% cycle 'row1' 'row2' as rowcolors %}">...</td>
<td class="{{ rowcolors }}">...</td>
</tr>
<tr>
<td class="{% cycle rowcolors %}">...</td>
<td class="{{ rowcolors }}">...</td>
</tr>
將輸出:
<tr>
<td class="row1">...</td>
<td class="row1">...</td>
</tr>
<tr>
<td class="row2">...</td>
<td class="row2">...</td>
</tr>
cycle 標簽中,通過空格分割,可以使用任意數量的值,被包含在單引號(')或者雙引號(")中的值被認為是可迭代字串,相反,沒有被引號包圍的值被當作模版變數,
debug
輸出整個除錯資訊,包括當前背景關系和匯入的模塊,
filter
通過一個或多個過濾器對內容過濾,需要結束標簽endfilter,
例如:
{% filter force_escape|lower %}
This text will be HTML-escaped, and will appear in all lowercase.
{% endfilter %}
firstof
輸出第一個不為False引數, 如果傳入的所有變數都為False,就什么也不輸出,
例如:
{% firstof var1 var2 var3 %}
它等價于:
{% if var1 %}
{{ var1 }}
{% elif var2 %}
{{ var2 }}
{% elif var3 %}
{{ var3 }}
{% endif %}
可以用一個默認字串作為輸出以防止傳入的所有變數都是False:
{% firstof var1 var2 var3 "fallback value" %}
ifchanged
檢查一個值是否在上一次的迭代中被改變了,
{% ifchanged %}標簽通常用在回圈里,它有兩個用處:
檢查已經渲染過的內容的當前狀態,并且只會顯示發生改變的內容,例如,以下的代碼是輸出days的串列項,不過它只會輸出被修改過月份的項:
<h1>Archive for {{ year }}</h1>
{% for date in days %}
{% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
<a href=https://www.cnblogs.com/wby-110/p/"{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
{% endfor %}
如果標簽內有多個值時,則會比較每一個值是否與上一次不同,例如,以下顯示每次更改時的日期,如果小時或日期已更改,則顯示小時:
{% for date in days %}
{% ifchanged date.date %} {{ date.date }} {% endifchanged %}
{% ifchanged date.hour date.date %}
{{ date.hour }}
{% endifchanged %}
{% endfor %}
ifchanged標記也可以采用可選的{% else %}將顯示值沒有改變的情況:
{% for match in matches %}
<div style="background-color:
{% ifchanged match.ballot_id %}
{% cycle "red" "blue" %}
{% else %}
gray
{% endifchanged %}
">{{ match }}</div>
{% endfor %}
lorem
用來在模版中提供文字樣本以供測驗用的,使用這個方法,可以幫你自動填充一些可以閱讀的內容,
{% lorem [count] [method] [random] %}
可以使用零個,一個,兩個或三個引數, 這些引數是:
- count :一個數字(或變數),其中包含要生成的段落或字數(默認值為1),
- method:HTML中使用p標簽、還是w標簽、還是b標簽,決定文本格式,默認是“b”,
- random:如果給出的話,random這個詞在生成文本時不會使用公共段落, 例子:
{% lorem %} # 將輸出常見的“lorem ipsum”段落,
{% lorem 3 p %} # 輸出常用的“lorem ipsum”段落和兩個隨機段落,每段包裹在<p>標簽中,
{% lorem 2 w random %} # 將輸出兩個隨機拉丁字,
now
顯示當前的日期或時間,可以指定顯示的格式, 如:
It is {% now "jS F Y H:i" %}
下面的例子中,“o”和“f”都被反斜杠轉義:
It is the {% now "jS \o\f F" %}
# 這將顯示為“It is the 4th of September”,
還可以使用語法{% now “Y” as current_year %}將輸出存盤在變數中,
{% now "Y" as current_year %}
{% blocktrans %}Copyright {{ current_year }}{% endblocktrans %}
regroup
用物件間共有的屬性重組串列,
對于下面的資料:
cities = [
{'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
{'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
{'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
{'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
{'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
]
如果你想顯示按國家/地區排序的分層串列,如下所示:
India
Mumbai: 19,000,000
Calcutta: 15,000,000
USA
New York: 20,000,000
Chicago: 7,000,000
Japan
Tokyo: 33,000,000
可以使用{% regroup %}標簽來給每個國家的城市分組:
{% regroup cities by country as country_list %}
<ul>
{% for country in country_list %}
<li>{{ country.grouper }}
<ul>
{% for city in country.list %}
<li>{{ city.name }}: {{ city.population }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
{% regroup %}有三個引數: 要重組的串列、用來分組的屬性、結果串列的名字,在這里,我們通過country屬性重新分組cities串列,并將結果保存在country_list中,
country_list的每個元素是具有兩個欄位的namedtuple()的實體:
- grouper - 分組的專案(例如,字串“India”或“Japan”),
- list - 此群組中所有專案的串列(例如,所有城市的串列,其中country ='India'),
resetcycle
重置先前的回圈,以便在下一次回圈時從其第一個專案重新啟動,如果沒有引數,{% resetcycle %}將重置最后一個{% cycle %},例:
{% for coach in coach_list %}
<h1>{{ coach.name }}</h1>
{% for athlete in coach.athlete_set.all %}
<p class="{% cycle 'odd' 'even' %}">{{ athlete.name }}</p>
{% endfor %}
{% resetcycle %}
{% endfor %}
這個示例將回傳下面的HTML:
<h1>José Mourinho</h1>
<p class="odd">Thibaut Courtois</p>
<p class="even">John Terry</p>
<p class="odd">Eden Hazard</p>
<h1>Carlo Ancelotti</h1>
<p class="odd">Manuel Neuer</p> # 第一個塊以class="odd"結束,新的以class="odd"開頭,沒有`{% resetcycle %}`標簽,第二個塊將以class="even"開始,
<p class="even">Thomas Müller</p>
還可以重置回圈標簽:
{% for item in list %}
<p class="{% cycle 'odd' 'even' as stripe %} {% cycle 'major' 'minor' 'minor' 'minor' 'minor' as tick %}">
{{ item.data }}
</p>
{% ifchanged item.category %}
<h1>{{ item.category }}</h1>
{% if not forloop.first %}{% resetcycle tick %}{% endif %}
{% endifchanged %}
{% endfor %}
在這個例子中,交替的奇數/偶數行和每五行出現一次的‘major’行,當類別更改時,只有五行周期被重置,
spaceless
洗掉HTML標簽之間的空白,包括制表符和換行,例:
{% spaceless %}
<p>
<a href=https://www.cnblogs.com/wby-110/p/"foo/">Foo</a>
</p>
{% endspaceless %}
# 將回傳下面的HTML:
<p><a href=https://www.cnblogs.com/wby-110/p/"foo/">Foo</a></p>
僅會洗掉tags之間的空格,不會洗掉標簽和文本之間的,例:
{% spaceless %}
<strong>
Hello # Hello周圍的空格不會被洗掉
</strong>
{% endspaceless %}
templatetag
輸出用于構成模板標簽的語法字符,
由于模板系統沒有“轉義”的概念,無法在HTML中使用‘\’轉義出類似{%的字符,為了顯示模板標簽本身,必須使用{% templatetag %}標簽,并添加相應的引數:
- openblock:
{% - closeblock:
%} - openvariable:
{{ - closevariable:
}} - openbrace :
{ - closebrace:
} - opencomment:
{# - closecomment:
#}
例如:
{% templatetag openblock %} url 'entry_list' {% templatetag closeblock %}
verbatim
禁止模版引擎在該標簽中進行渲染作業,
常見的用法是允許與Django語法沖突的JavaScript模板圖層作業, 像這樣:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
widthratio
為了創建柱狀形圖,此標簽計算給定值與最大值的比率,然后將該比率應用于常量,
如:
<img src=https://www.cnblogs.com/wby-110/p/"bar.png" alt="Bar"
height="10" width="{% widthratio this_value max_value max_width %}" />
如果this_value是175,max_value是200,并且max_width是100,則示例中的影像將是88像素寬(因為175 / 200 = .875; .875 * 100 = 87.5,四舍五入入為88),
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/79346.html
標籤:Python
下一篇:GitHub(國內)加速
