django中嵌入html的語法

lm_y發表於2017-08-26

原文件:

https://docs.djangoproject.com/en/1.8/topics/templates/#the-django-template-language

總結如下:

Django模板語言 The Django template language

模板中常用的語法規則

{最新版本的Django語法可能有改變,不支援的操作可能支援了。[HTML教程 - 基本元素/標籤及屬性]}

Django變數Variables

A variable outputs a value from the context, which is a dict-like objectmapping keys to values.

Variables are surrounded by {{ and}} like this:

My first name is {{ first_name }}. My last name is {{ last_name }}.
With a context of {'first_name':'John','last_name':'Doe'}
Django 模板標籤
if/else 標籤
1. 基本語法格式如下:
{% if condition %}
     ... display
{% endif %}

或者:

{% if condition1 %}
   ... display 1
{% elif condiiton2 %}
   ... display 2
{% else %}
   ... display 3
{% endif %}

根據條件判斷是否輸出。if/else 支援巢狀。

Note:模板標籤中的變數是不用{{}}包含的。

2. {% if %} 標籤接受 and , or 或者 not 關鍵字來對多個變數做判斷 ,或者對變數取反( not ),例如:

{% if athlete_list and coach_list %}
     athletes 和 coaches 變數都是可用的。
{% endif %}

Note:

1. {% if %} 標籤不允許在同一個標籤中同時使用 andor ,因為邏輯上可能模糊的,這樣的程式碼是不合法的:

{% if athlete_list and coach_list or cheerleader_list %}
2. 系統不支援用圓括號來組合比較操作。 如果你確實需要用到圓括號來組合表達你的邏輯式,考慮將它移到模板之外處理,然後以模板變數的形式傳入結果吧。 或者,僅僅用巢狀的{%if%}標籤替換

for 標籤

1. {% for %} 允許我們在一個序列上迭代。與Python的 for 語句的情形類似,迴圈語法是 for X in Y ,Y是要迭代的序列而X是在每一個特定的迴圈中使用的變數名稱。

每一次迴圈中,模板系統會渲染在 {% for %} 和 {% endfor %} 之間的所有內容。

例如,給定一個運動員列表 athlete_list 變數,我們可以使用下面的程式碼來顯示這個列表:
<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>

2. 給標籤增加一個 reversed 使得該列表被反向迭代:

{% for athlete in athlete_list reversed %}

3. 可以巢狀使用 {% for %} 標籤。

在執行迴圈之前先檢測列表的大小是一個通常的做法,當列表為空時輸出一些特別的提示。`` for`` 標籤支援一個可選的`` {% empty %}`` 分句,通過它我們可以定義當列表為空時的輸出內容 下面的例子與用if-else實現等價:

{% for athlete in athlete_list %}
    <p>{{ athlete.name }}</p>
{% empty %}
    <p>There are no athletes. Only computer programmers.</p>
{% endfor %}

4. Django不支援退出迴圈操作。 如果我們想退出迴圈,可以改變正在迭代的變數,讓其僅僅包含需要迭代的專案。 同理,Django也不支援continue語句,我們無法讓當前迭代操作跳回到迴圈頭部。

5.在每個`` {% for %}``迴圈裡有一個稱為`` forloop`` 的模板變數。這個變數有一些提示迴圈進度資訊的屬性。

forloop.counter 總是一個表示當前迴圈的執行次數的整數計數器。 這個計數器是從1開始的,所以在第一次迴圈時forloop.counter 將會被設定為1。

{% for item in todo_list %}
    <p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}

forloop.counter0 類似於forloop.counter ,但是它是從0計數的。 第一次執行迴圈時這個變數會被設定為0。

forloop.revcounter 是表示迴圈中剩餘項的整型變數。 在迴圈初次執行時forloop.revcounter 將被設定為序列中項的總數。 最後一次迴圈執行中,這個變數將被置1。

forloop.revcounter0 類似於forloop.revcounter ,但它以0做為結束索引。在第一次執行迴圈時,該變數會被置為序列的項的個數減1。

forloop.first 是一個布林值,如果該迭代是第一次執行,那麼它被置為```` 在下面的情形中這個變數是很有用的:

System Message: WARNING/2 (<string>, line 1071);backlink

Inline literal start-string without end-string.

{% for object in objects %}
    {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
    {{ object }}
    </li>
{% endfor %}

forloop.last 是一個布林值;在最後一次執行迴圈時被置為True。 一個常見的用法是在一系列的連結之間放置管道符(|),另一個常見的用途是為列表的每個單詞的加上逗號。

{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}

上面的模板可能會產生如下的結果:

Link1 | Link2 | Link3 | Link4
      forloop.parentloop 是一個指向當前迴圈的上一級迴圈的forloop 物件的引用(在巢狀迴圈的情況下)。
{% for country in countries %}
    <table>
    {% for city in country.city_list %}
        <tr>
        <td>Country #{{ forloop.parentloop.counter }}</td>
        <td>City #{{ forloop.counter }}</td>
        <td>{{ city }}</td>
        </tr>
    {% endfor %}
    </table>
{% endfor %}

forloop 變數僅僅能夠在迴圈中使用。 在模板解析器碰到{%endfor%}標籤後,forloop就不可訪問了。

6. Context和forloop變數

在一個 {% for%} 塊中,已存在的變數會被移除,以避免forloop 變數被覆蓋。 Django會把這個變數移動到forloop.parentloop 中。通常我們不用擔心這個問題,但是一旦我們在模板中定義了forloop 這個變數(當然我們反對這樣做),在{%for%} 塊中它會在forloop.parentloop 被重新命名。

ifequal/ifnotequal 標籤

1. {% ifequal %} 標籤比較兩個值,當他們相等時,顯示在 {% ifequal %} 和 {% endifequal %} 之中所有的值。

下面的例子比較兩個模板變數 user 和 currentuser :

{% ifequal user currentuser %}
    <h1>Welcome!</h1>
{% endifequal %}

Note:只有模板變數,字串,整數和小數可以作為 {% ifequal %} 標籤的引數。其他任何型別,例如python的字典型別、列表型別、布林型別,不能用在{%ifequal%} 中。

2. {% ifequal %} 支援可選的 {% else%} 標籤:8

{% ifequal section 'sitenews' %}
    <h1>Site News</h1>
{% else %}
    <h1>No News Here</h1>
{% endifequal %}

註釋標籤

1. Django單行註釋使用 {# #}。

{# 這是一個註釋 #}

用這種語法的註釋不能跨越多行。 這個限制是為了提高模板解析的效能。 在下面這個模板中,輸出結果和模板本身是 完全一樣的(也就是說,註釋標籤並沒有被解析為註釋):

This is a {# this is not
a comment #}
test.

2. 實現多行註釋,可以使用`` {% comment %}`` 模板標籤

{% comment %}
This is a
multi-line comment.
{% endcomment %}
過濾器

1. 模板過濾器可以在變數被顯示前修改它,過濾器使用管道字元,如下所示:

{{ name|lower }}

{{ name }} 變數被過濾器 lower 處理後,文件大寫轉換文字為小寫。

2. 過濾管道可以被* 套接* ,既是說,一個過濾器管道的輸出又可以作為下一個管道的輸入:

{{ my_list|first|upper }}

以上例項將第一個元素並將其轉化為大寫。

Note:另一種實現

{{ django|title }}
3. 有些過濾器有引數。 過濾器的引數跟隨冒號之後並且總是以雙引號包含。 例如:
{{ bio|truncatewords:"30" }}

這個將顯示變數 bio 的前30個詞。

4.linebreaks

Replaces line breaks in plain text with appropriate HTML; a singlenewline becomes an HTML line break (<br/>) and a new linefollowed by a blank line becomes a paragraph break (</p>).

For example:

{{ value|linebreaks }}

If value is Joel\nis a slug, the output will be<p>Joel<br/>isaslug</p>.

linebreaksbr

Converts all newlines in a piece of plain text to HTML line breaks(<br/>).

For example:

{{ value|linebreaksbr }}

If value is Joel\nis a slug, the output will beJoel<br/>isaslug.

5. 其他過濾器
  • addslashes : 新增反斜槓到任何反斜槓、單引號或者雙引號前面。
  • date : 按指定的格式字串引數格式化 date 或者 datetime 物件,例項:
    {{ pub_date|date:"F j, Y" }}     #將變數ship_date傳遞給date過濾器,同時指定引數”F j,Y”。date過濾器根據引數進行格式輸出。如時間的顯示 April 2, 2009 是按 'F j, Y' 格式顯示的。
  • length : 返回變數的長度。你可以對列表或者字串,或者任何知道怎麼測定長度的Python 物件使用這個方法(也就是說,有 __len__() 方法的物件)。

Note:過濾器是用管道符(|)來呼叫的,具體可以參見Unix管道符。

[Built-in filter reference]

[Writing custom template filters]

include 標籤
該標籤允許在(模板中)包含其它的模板的內容。 標籤的引數是所要包含的模板名稱,可以是一個變數,也可以是用單/雙引號硬編碼的字串。 每當在多個模板中出現相同的程式碼時,就應該考慮是否要使用{%include%} 來減少重複。

下面這兩個例子都包含了 nav.html 模板:

{% include "nav.html" %}

Note:

1. 和在 get_template() 中一樣, 對模板的檔名進行判斷時會在所調取的模板名稱之前加上來自TEMPLATE_DIRS 的模板目錄。

2.如果{%include%}標籤指定的模板沒找到,Django將會在下面兩個處理方法中選擇一個:

  • 如果 DEBUG 設定為 True ,你將會在 Django 錯誤資訊頁面看到TemplateDoesNotExist 異常。

  • 如果 DEBUG 設定為 False ,該標籤不會引發錯誤資訊,在標籤位置不顯示任何東西。

URL標籤

url的用法也很簡單,只要在urlpatterns裡使用它,附加一個name,如:

url(r'^article$','news_index' ,name="news_index"),
Templates裡 這樣使用
{%url 'name'%}
地址連結就能使用了。

Note:name是全域性的,你整個urlpatterns裡只能一個唯一的name,這個道理應該好理解,就像網站的地址也是唯一性的。

views裡怎麼用以及urlpatterns的地址包含有引數的時候<a href="{%url 'news_archive' 2010  02%}">2010年02月</a>時可參考[Django url 標籤的使用]


模板繼承

模板可以用繼承的方式來實現複用。在整個網站中,如何減少共用頁面區域(比如站點導航)所引起的重複和冗餘程式碼?

解決該問題的傳統做法是使用 伺服器端的 includes ,你可以在 HTML 頁面中使用該指令將一個網頁嵌入到另一箇中。 事實上, Django 通過剛才講述的 {% include %} 支援了這種方法。 但是用 Django 解決此類問題的首選方法是使用更加優雅的策略—— 模板繼承 。本質上來說,模板繼承就是先構造一個基礎框架模板,而後在其子模板中對它所包含站點公用部分和定義塊進行過載。你可以將其視為伺服器端 include 的逆向思維版本。 你可以對那些 不同 的程式碼段進行定義,而不是 共同 程式碼段。

第一步是定義 基礎模板 , 該框架之後將由 子模板 所繼承。 基礎模板:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <h1>My helpful timestamp site</h1>
    {% block content %}{% endblock %}
    {% block footer %}
    <hr>
    <p>Thanks for visiting my site.</p>
    {% endblock %}
</body>
</html>
Note:

1. 所有的 {% block %} 標籤告訴模板引擎,子模板可以過載這些部分。每個{%block%}標籤所要做的是告訴模板引擎,該模板下的這一塊內容將有可能被子模板覆蓋。

2.注意由於子模板並沒有定義 footer 塊,模板系統將使用在父模板中定義的值。 父模板{%block%} 標籤中的內容總是被當作一條退路。

3. 繼承並不會影響到模板的上下文。 換句話說,任何處在繼承樹上的模板都可以訪問到你傳到模板中的每一個模板變數。

4. 你可以根據需要使用任意多的繼承次數。

使用繼承的一種常見方式是下面的三層法:

  1. 建立 base.html 模板,在其中定義站點的主要外觀感受。 這些都是不常修改甚至從不修改的部分。

  1. 為網站的每個區域建立 base_SECTION.html 模板(例如,base_photos.htmlbase_forum.html )。這些模板對base.html 進行擴充,幷包含區域特定的風格與設計。

  2. 為每種型別的頁面建立獨立的模板,例如論壇頁面或者圖片庫。 這些模板擴充相應的區域模板。

使用模板繼承的一些訣竅:

  • 如果在模板中使用 {%extends%} ,必須保證其為模板中的第一個模板標記。 否則,模板繼承將不起作用。

  • 一般來說,基礎模板中的 {%block%} 標籤越多越好。記住,子模板不必定義父模板中所有的程式碼塊,因此你可以用合理的預設值對一些程式碼塊進行填充,然後只對子模板所需的程式碼塊進行(重)定義。 俗話說,鉤子越多越好。

  • 如果發覺自己在多個模板之間拷貝程式碼,你應該考慮將該程式碼段放置到父模板的某個 {% block %} 中。

  • 如果你需要訪問父模板中的塊的內容,使用 {{block.super}}這個標籤吧,這一個魔法變數將會表現出父模板中的內容。 如果只想在上級程式碼塊基礎上新增內容,而不是全部過載,該變數就顯得非常有用了。

  • 不允許在同一個模板中定義多個同名的 {%block%} 。 存在這樣的限制是因為block 標籤的工作方式是雙向的。 也就是說,block 標籤不僅挖了一個要填的坑,也定義了在模板中這個坑所填充的內容。如果模板中出現了兩個相同名稱的{% block %} 標籤,父模板將無從得知要使用哪個塊的內容。

  • {%extends%} 對所傳入模板名稱使用的載入方法和get_template() 相同。 也就是說,會將模板名稱被新增到TEMPLATE_DIRS 設定之後。

  • 多數情況下, {%extends%} 的引數應該是字串,但是如果直到執行時方能確定父模板名,這個引數也可以是個變數。 這使得你能夠實現一些很酷的動態功能。

相關文章