Django 模版語言詳解

一.簡介

模版是純文本文件。它能夠產生任何基於文本的的格式(HTML,XML,CSV等等)。css

模版包括在使用時會被值替換掉的 變量,和控制模版邏輯的 標籤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 %}

二.使用

1.變量

格式:python

{{ variable }}

變量命名規則django

1.變量的命名包括任何字母數字以及下劃線 ("_")的組合api

2.不能在變量名稱中使用空格和標點符號服務器

當模版系統遇到點("."),它將以這樣的順序查詢:app

  • 字典查詢(Dictionary lookup)
  • 屬性或方法查詢(Attribute or method lookup)
  • 數字索引查詢(Numeric index lookup)

例;dom

 
 
{#若是後臺 渲染傳過來的是字典格式的數據 那麼前端頁面解析值 dict={"k1":"v1"} 假設傳的是{"dict": dict} 前端頁面取值 .字典key值#}
 
<h1>{{dict.k1}}</h1>

2.過濾器

  能夠經過使用 過濾器來改變變量的顯示ide

格式:

{{ name|lower }}

管道符過濾,過濾器可以被「串聯」。一個過濾器的輸出將被應用到下一個

過濾器參數;

{{ item.content |truncatewords:30 }}  <!-- 只顯示 content 變量的前30個詞 -->

default

{{ value|default:"nothing" }}   <!--若是一個變量是false或者爲空,使用給定的默認值。不然,使用變量的值-->

length

返回值的長度。它對字符串和列表都起做用

{{ value|length }}

filesizeformat

將該數值格式化爲一個 「人類可讀的」 文件容量大小 (例如 '13 KB''4.1 MB''102 bytes', 等等)

{{ value|filesizeformat }}

add

把add後的參數加給value

{{ value|add:"2" }}  <!--若是 value 爲 4,則會輸出 6.-->

capfirst

將變量首字母變大寫

{{ value|capfirst }}  <!--若是value是test過濾後轉爲Test-->

cut

移除value中全部的與給出的變量相同的字符串

{{ value|cut:" " }}

dictsort

根據指定的key值對列表字典排序,並返回

{{ value|dictsort:"name" }}

如,給定的值是:

[
    {'name': 'peter', 'age': 19},
    {'name': 'amy', 'age': 22},
    {'name': 'jim', 'age': 31},
]

那麼結果將是;

[
    {'name': 'amy', 'age': 22},
    {'name': 'jim', 'age': 31},
    {'name': 'peter', 'age': 19},
]

也能夠處理較爲複雜的;

{% for book in books|dictsort:"author.age" %}
    * {{ book.title }} ({{ book.author.name }})
{% endfor %}

如給定值爲:

[
    {'title': '1984', 'author': {'name': 'George', 'age': 45}},
    {'title': 'Timequake', 'author': {'name': 'Kurt', 'age': 75}},
    {'title': 'Alice', 'author': {'name': 'Lewis', 'age': 33}},
]

那麼結果爲:

* Alice (Lewis)
* 1984 (George)
* Timequake (Kurt)

random

隨機返回一個值

{{ value|random }}

若是 value 是 列表 ['a', 'b', 'c', 'd'], 可能輸出的是 "b"

slice

切片

{{ some_list|slice:":2" }}

若是 some_list 是 ['a', 'b', 'c'], 輸出結果爲 ['a', 'b']

truncatewords

字符串截斷

{{ value|truncatewords:2 }}

若是 value 是 "Joel is slug",輸出  "Joel is ...".

3.標籤

格式

{% tag %}

簡介

標籤比變量複雜得多:有些用於在輸出中建立文本,有些用於控制循環或邏輯,有些用於加載外部信息到模板中供之後的變量使用。

有些標籤須要開始標籤和結束標籤(例如{% tag %} ... tag contents ... {% endtag %}

經常使用標籤;

for標籤

格式

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

if,elif and else

計算一個變量,而且當變量是「true」時,顯示塊中的內容

格式:

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

4.註釋

  要註釋模版中一行的部份內容,使用註釋語法 {# #}

三.模版繼承

模版繼承可讓您建立一個基本的「骨架」模版,它包含您站點中的所有元素,而且能夠定義可以被子模版覆蓋的 blocks 。

例;

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}My amazing site{%/span> endblock %}</title>
</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骨架。「子模版」的工做是用它們的內容填充空的blocks

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

{% extends "base.html" %}/span>

{% block title %}My amazing blog{% endblock %}

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

extends 標籤是這裏的關鍵。它告訴模版引擎,這個模版「繼承」了另外一個模版。當模版系統處理這個模版時,首先,它將定位父模版——在此例中,就是「base.html」。

模版引擎將注意到 base.html 中的三個 block 標籤,並用子模版中的內容來替換這些block。根據 blog_entries 的值,輸出可能看起來是這樣的:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>My amazing blog</title>
</head>

<body>
    <div id="sidebar">
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
    </div>

    <div id="content">
        <h2>Entry one</h2>
        <p>This is my first entry.</p>

        <h2>Entry two</h2>
        <p>This is my second entry.</p>
    </div>
</body>
</html>

使用繼承的一個經常使用方式是相似下面的三級結構:

  • 建立一個 base.html 模版來控制您整個站點的主要視覺和體驗。
  • 爲您的站點的每個「分支」建立一個base_SECTIONNAME.html 模版。例如, base_news.htmlbase_sports.html這些模版都繼承自 base.html ,而且包含了每部分特有的樣式和設計。
  • 爲每一種頁面類型建立獨立的模版,例如新聞內容或者博客文章。這些模版繼承對應分支的模版

母版結構

{% block content %}
...
{% endblock content %}

四.自動HTML轉義

默認狀況下,Django 中的每一個模板會自動轉義每一個變量的輸出。明確地說,下面五個字符被轉義:

  • < 會轉換爲&lt;
  • > 會轉換爲&gt;
  • ' (單引號) 會轉換爲&#39;
  • " (雙引號)會轉換爲 &quot;
  • & 會轉換爲 &amp;

如何關閉

4.1 用於模板代碼塊

要控制模板上的自動轉義,將模板(或者模板中的特定區域)包裹在autoescape標籤 中

{% autoescape off %}
    Hello {{ name }}
{% endautoescape %}

autoescape標籤接受on 或者 off做爲它的參數。有時你可能想在自動轉義關閉的狀況下強制使用它。下面是一個模板的示例:

Auto-escaping is on by default. Hello {{ name }}

{% autoescape off %}
    This will not be auto-escaped: {{ data }}.

    Nor this: {{ other_data }}
    {% autoescape on %}
        Auto-escaping applies again: {{ name }}
    {% endautoescape %}
{% endautoescape %}

自動轉義標籤做用於擴展了當前模板的模板,以及經過 include 標籤包含的模板,就像全部block標籤那樣。例如:

{% autoescape off %}
<h1>{% block title %}{% endblock %}</h1>
{% block content %}
{% endblock %}
{% endautoescape %}
base.html
{% extends "base.html" %}
{% block title %}This &amp; that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}
child.html

五.自定義simple_tag

自定義simple_tag

{% load humanize %}

{{ 45000|intcomma }}

上面的例子中, load標籤加載了humanize標籤庫,以後咱們可使用intcomma過濾器。若是你開啓了django.contrib.admindocs,你能夠查詢admin站點中的文檔部分,來尋找你的安裝中的自定義庫列表。

load標籤能夠接受多個庫名稱,由空格分隔。例如

{% load humanize i18n %}

5.1 自定義標籤代碼而已

自定義模板標籤和過濾器必須位於Django 的某個應用中。若是它們與某個已存在的應用相關,那麼將其與應用綁在一塊兒纔有意義;不然,就應該建立一個新的應用來包含它。

這個應用應該包含一個templatetags 目錄,和models.pyviews.py等文件處於同一級別目錄下,若是目錄不存在則建立它——不要忘記建立__init__.py 文件以使得該目錄能夠做爲Python 的包。在添加這個模塊之後,在模板裏使用標籤或過濾器以前你將須要重啓服務器。新建 PY文件

切記:目錄名必定要是templatetags

如:

#!/usr/bin/env python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe
from django.template.base import resolve_variable, Node, TemplateSyntaxError
  
register = template.Library()
  
@register.simple_tag
def my_simple_time(v1,v2,v3):
    return  v1 + v2 + v3
  
@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

而後在你的模板中你應當這樣使用

{% load extend_temp %}

爲了成爲一個可用的標籤庫,這個模塊必須包含一個名爲 register的變量,它是template.Library 的一個實例,全部的標籤和過濾器都是在其中註冊的。因此把以下的內容放在你的模塊的頂部:

from django import template

register = template.Library()

5.2 編寫自定義模板過濾器

自定義過濾器就是一個帶有一個或兩個參數的Python 函數:

  • (輸入的)變量的值 —— 不必定是字符串形式。
  • 參數的值 —— 能夠有一個初始值,或者徹底不要這個參數。

例如,在{{ var|foo:"bar" }}中,foo過濾器應當傳入變量var和參數 "bar"

因爲模板語言沒有提供異常處理,任何從過濾器中拋出的異常都將會顯示爲服務器錯誤。所以,若是有合理的值能夠返回,過濾器應該避免拋出異常。在模板中有一個明顯錯誤的狀況下,引起一個異常可能仍然要好於用靜默的失敗來掩蓋錯誤

例 ;

def cut(value, arg):
    """Removes all values of arg from the given string"""
    return value.replace(arg, '')

下面是這個過濾器應該如何使用

{{ somevariable|cut:"0" }}

大多數過濾器沒有參數。在這種狀況下,你的函數不帶這個參數便可。示例︰

def lower(value): # 只能是一個參數.
    """變小寫"""
    return value.lower()

5.3 註冊自定義過濾器

django.template.Library.filter()

一旦你寫好了你的自定義過濾器函數,你就開始須要把它註冊爲你的 Library實例,來讓它在Django模板語言中可用

register.filter('cut', cut)
register.filter('lower', lower)

Library.filter()方法須要兩個參數:

  1. 過濾器的名稱(一個字符串對象)
  2. 編譯的函數 – 一個Python函數(不要把函數名寫成字符串)

你還能夠把register.filter()用做裝飾器:

@register.filter(name='cut')
def cut(value, arg):
    return value.replace(arg, '')

@register.filter
def lower(value):
    return value.lower()
@register.filter
def detail3(value,arg):

    """
    查看餘數是否等於remainder arg="1,2"
    :param counter:
    :param allcount:
    :param remainder:
    :return:
    """
    allcount, remainder = arg.split(',')
    allcount = int(allcount)
    remainder = int(remainder)
    if value%allcount == remainder:
        return True
    return False

 

詳細參考:http://python.usyiyi.cn/django/howto/custom-template-tags.html

相關文章
相關標籤/搜索