1. 程式人生 > 實用技巧 >轉:django模板標籤

轉:django模板標籤

Django內建模板標籤

閱讀:31262評論:13


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 上下文變數管理器

1. autoescape

控制自動轉義是否可用。引數是on或off。 該標籤會以一個endautoescape作為結束標籤.

例如:

{% autoescape on %}
    {{ body }}
{% endautoescape %}

2. block

block標籤可以被子模板覆蓋。

3. 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標籤不能巢狀使用。

4. csrf_token

這個標籤用於跨站請求偽造保護。常用於為form表單提供csrf令牌。

5. cycle

每當這個標籤被訪問,返回它的下一個元素。第一次訪問返回第一個元素,第二次訪問返回第二個引數,以此類推. 一旦所有的變數都被訪問過了,就會回到最開始的地方,重複下去。這個標籤在迴圈中特別有用:

{% for o in some_list %}
    <tr class="{% cycle 'row1' 'row2'%}">
        ...
    </tr>
{% endfor %}

第一次迭代產生的HTML引用了row1類,第二次則是row2類,第三次又是row1 類,如此類推。

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 標籤中,通過空格分割,可以使用任意數量的值。被包含在單引號(')或者雙引號(")中的值被認為是可迭代字串,相反,沒有被引號包圍的值被當作模版變數。

6. debug

輸出整個除錯資訊,包括當前上下文和匯入的模組。

7. extends

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

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

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

Django1.10中添加了使用相對路徑的能力。通常模板名稱是相對於模板載入器的根目錄。字串引數也可以是以./../開頭的相對路徑。 例如,假設有以下目錄結構:

dir1/
    template.html
    base2.html
    my/
        base3.html
base1.html

在template.html中,以下路徑將有效:

{% extends "./base2.html" %}
{% extends "../base1.html" %}
{% extends "./my/base3.html" %}

8. filter

通過一個或多個過濾器對內容過濾。需要結束標籤endfilter。

例如:

{% filter force_escape|lower %}
    This text will be HTML-escaped, and will appear in all lowercase.
{% endfilter %}

9. firstof

輸出第一個不為False引數。 如果傳入的所有變數都為False,就什麼也不輸出。

例如:

{% firstof var1 var2 var3 %}

它等價於:

{% if var1 %}
    {{ var1 }}
{% elif var2 %}
    {{ var2 }}
{% elif var3 %}
    {{ var3 }}
{% endif %}

當然也可以用一個預設字串作為輸出以防止傳入的所有變數都是False:

{% firstof var1 var2 var3 "fallback value" %}

10. for

迴圈物件中的每一個元素

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>

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

如果迴圈物件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 %}

請記住,對於點運算子,字典鍵查詢優先於方法查詢。

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

  • forloop.counter:迴圈的當前索引值,從1開始計數;常用於生成一個表格或者列表的序號!
  • forloop.counter0:迴圈的當前索引值,從0開始計數;
  • forloop.revcounter: 迴圈結束的次數(從1開始)
  • forloop.revcounter0 迴圈結束的次數(從0開始)
  • forloop.first:判斷當前是否迴圈的第一次,是的話,該變數的值為True。我們經常要為第一行加點特殊的對待,就用得上這個判斷了,結合if。
  • forloop.last:如果這是最後一次迴圈,則為真
  • forloop.parentloop:對於巢狀迴圈,返回父迴圈所在的迴圈次數。某些場景下,這是個大殺器,能解決你很多頭疼的問題。

11. 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>

它和下面的例子作用相等,但是更簡潔、更清晰甚至可能執行起來更快:

<ul>
  {% if athlete_list %}
    {% for athlete in athlete_list %}
      <li>{{ athlete.name }}</li>
    {% endfor %}
  {% else %}
    <li>Sorry, no athletes in this list.</li>
  {% endif %}
</ul>

12. if

{% if %}會對一個變數求值,如果它的值是“True”(存在、不為空、且不是boolean型別的False值),這個內容塊就會輸出:

{% 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 %}

上述例子中,如果athlete_list不為空,就會通過使用{{ athlete_list|length }}過濾器展示出athletes的數量。

if標籤之後可以帶有一個或者多個{% elif %}從句,也可以帶有一個{% else %}從句以便在之前的所有條件不成立的情況下完成執行。這些從句都是可選的。

布林運算子:

if標籤可以使用not,and或or來測試布林值:

{% 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 %}

允許同時使用and和or子句,and的優先順序高於or :

{% if athlete_list and coach_list or cheerleader_list %}

將解釋如下:

if (athlete_list and coach_list) or cheerleader_list

在if標籤中使用實際括號是錯誤的語法,這點不同於Python。如果需要為它們指示優先順序,應使用巢狀的if標籤。

if標籤允許使用這些操作符:==,!=,<,>,<=,>=,in,not in,is,is not,如下面的列子所示:

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

{% if somevar != "x" %}
  This appears if variable somevar does not equal the string "x",
  or if somevar is not found in the context
{% endif %}

{% if somevar < 100 %}
  This appears if variable somevar is less than 100.
{% endif %}

{% if somevar > 0 %}
  This appears if variable somevar is greater than 0.
{% endif %}

{% if somevar <= 100 %}
  This appears if variable somevar is less than 100 or equal to 100.
{% endif %}

{% if somevar >= 1 %}
  This appears if variable somevar is greater than 1 or equal to 1.
{% endif %}

{% if "bc" in "abcdef" %}
  This appears since "bc" is a substring of "abcdef"
{% endif %}

{% if "hello" in greetings %}
  If greetings is a list or set, one element of which is the string
  "hello", this will appear.
{% endif %}

{% if user not in users %}
  If users is a QuerySet, this will appear if user is not an
  instance that belongs to the QuerySet.
{% endif %}

{% if somevar is True %}
  This appears if and only if somevar is True.
{% endif %}

{% if somevar is None %}
  This appears if somevar is None, or if somevar is not found in the context.
{% endif %}

{% if somevar is not True %}
  This appears if somevar is not True, or if somevar is not found in the
  context.
{% endif %}

{% if somevar is not None %}
  This appears if and only if somevar is not None.
{% endif %}

也可以在if表示式中使用過濾器。 像這樣:

{% if messages|length >= 100 %}
   You have lots of messages today!
{% endif %}

所有上述操作符都可以組合以形成複雜表示式。對於這樣的表示式,重要的是優先順序規則。操作符的優先順序從低至高如下:

or
and
not
in
==,!=,<,>,<= ,>=

與Python的規則是一樣的。 所以,對於下面的複雜if標籤:

{% if a == b or c == d and e %}

將被解釋為:

(a == b) or ((c == d) and e)

如果想要不同的優先順序,那麼你需要使用巢狀的if標籤,而不能使用圓括號。

比較運算子不能像Python或數學符號中那樣“連結”。例如,不能使用:

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

應該使用:

{% if a > b and b > c %}

13. ifequal和ifnotequal

{% ifequal a b %} ... {% endifequal %}是一種過時的寫法,等同於{% if a == b %} ... {% endif %}。 同樣,{% ifnotequal a b %} ... {% endifnotequal %}等同於{% if a != b %} ... {% endif %}。這兩個標籤將在以後的版本中棄用。

14. ifchanged

檢查一個值是否在上一次的迭代中被改變了。

{% ifchanged %}標籤通常用在迴圈裡。它有兩個用處:

檢查已經渲染過的內容的當前狀態。並且只會顯示發生改變的內容。例如,以下的程式碼是輸出days的列表項,不過它只會輸出被修改過月份的項:

<h1>Archive for {{ year }}</h1>

{% for date in days %}
    {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
    <a href="{{ 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=" color: rgb(0, 0, 255);">{% ifchanged match.ballot_id %}
            {% cycle "red" "blue" %}
        {% else }
            gray
        {% endifchanged }
    ">{{ match }}</div>
{% endfor %}

15. include

載入指定的模板並以標籤內的引數渲染。這是一種引入別的模板的方法,一定要將include和extend區分開!include類似Python的import。

{% include "foo/bar.html" %}

也可以使用變數名template_name

{% 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 %}

include標籤應該被理解為是一種"將子模版渲染並嵌入當前HTML中"的變種方法,而不應該看作是"解析子模版並在被父模版包含的情況下展現其被父模版定義的內容"。這意味著在不同的被包含的子模版之間並不共享父模版的狀態,每一個子包含都是完全獨立的渲染過程。

16. load

載入自定義模板標籤。

下面的模板將會從somelibrary和package包中的otherlibrary中載入所有已經註冊的標籤和過濾器:

{% load somelibrary package.otherlibrary %}

還可以使用from引數從庫中選擇性載入單個過濾器或標記。

{% load foo bar from somelibrary %}

17. lorem

這個標籤是用來在模版中提供文字樣本以供測試用的。使用場景是什麼?

比如你要寫個demo,裡面要有一大段的文字和篇章,你不可能真的去寫一篇文章吧?如果懶得去網上COPY,又不願意使用一堆毫無意義雜亂的亂碼,那麼使用這個方法,可以幫你自動填充一些可以閱讀的內容。

PS:Django考慮得真細.....

用法:

{% lorem [count] [method] [random] %}

可以使用零個,一個,兩個或三個引數。 這些引數是:

  • count :一個數字(或變數),其中包含要生成的段落或字數(預設值為1)。
  • method:HTML中使用p標籤、還是w標籤、還是b標籤,決定文字格式。預設是“b”。
  • random:如果給出的話,random這個詞在生成文字時不會使用公共段落。 例子:
{% lorem %}將輸出常見的“lorem ipsum”段落。
{% lorem 3 p %}輸出常用的“lorem ipsum”段落和兩個隨機段落,每段包裹在HTML`<p>`標籤中。
{% lorem 2 w random %}將輸出兩個隨機拉丁字。

18. 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 %}

19. 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')。

20. resetcycle

Django1.11中的新功能。

重置先前的迴圈,以便在下一次迴圈時從其第一個專案重新啟動。如果沒有引數,{% 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>
<p class="even">Thomas Müller</p>

注意第一個塊以class="odd"結束,新的以class="odd"開頭。沒有{% resetcycle %}標籤,第二個塊將以class="even"開始。

還可以重置迴圈標籤:

{% 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’行。當類別更改時,只有五行週期被重置。

21. spaceless

刪除HTML標籤之間的空白,包括製表符和換行。

用法示例:

{% spaceless %}
    <p>
        <a href="foo/">Foo</a>
    </p>
{% endspaceless %}

這個示例將返回下面的HTML:

<p><a href="foo/">Foo</a></p>

僅會刪除tags之間的空格,不會刪除標籤和文字之間的。下面的例子中,Hello周圍的空格不會被刪除:

{% spaceless %}
    <strong>
        Hello
    </strong>
{% endspaceless %}

22. templatetag

輸出用於構成模板標籤的語法字元。

由於模板系統沒有“轉義”的概念,無法在HTML中使用‘\’轉義出類似{%的字元。為了顯示模板標籤本身,必須使用{% templatetag %}標籤,並新增相應的引數:

  • openblock:{%
  • closeblock:%}
  • openvariable:{{
  • closevariable:}}
  • openbrace :{
  • closebrace:}
  • opencomment:{#
  • closecomment:#}

例如:

{% templatetag openblock %} url 'entry_list' {% templatetag closeblock %}

23. 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="{{ the_url }}">I'm linking to {{ the_url }}</a>

如果檢視不存在,{% url ... as var %}語法不會導致錯誤。

{% url 'some-url-name' as the_url %}
{% if the_url %}
  <a href="{{ the_url }}">Link to optional stuff</a>
{% endif %}

如果使用urlconf的名稱空間網址,通過冒號指定完全名稱,如下所示:

{% url 'myapp:view-name' %}

再次強調,是冒號,不是圓點不是斜槓!

24. verbatim

禁止模版引擎在該標籤中進行渲染工作。

常見的用法是允許與Django語法衝突的JavaScript模板圖層工作。 像這樣:

{% verbatim %}
    {{if dying}}Still alive.{{/if}}
{% endverbatim %}

25. widthratio

為了建立柱狀形圖,此標籤計算給定值與最大值的比率,然後將該比率應用於常量。

像這樣:

<img src="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)。

26. with

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

像這樣:

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

total只在with標籤內部有效。

可以分配多個變數:

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