Django 模版語言詳解


一.簡介

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

模版包括在使用時會被值替換掉的 變量,和控制模版邏輯的 標簽

例:

{% 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.變量

格式:

{{ variable }}

變量命名規則

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

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

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

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

例;

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

2.過濾器

  可以通過使用 過濾器來改變變量的顯示

格式:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM