1. 程式人生 > >Django之模版語法

Django之模版語法

1.模版語法之變數

在 Django 模板中遍歷複雜資料結構的關鍵是句點字元, 語法:

  {{var_name}}
檢視函式:views.py
def index(request):
    import datetime
    s="hello"
    l=[111,222,333]    
    dic={"name":"yuan","age":18}  
    date = datetime.date(1993, 5, 2)   

    class Person(object):
        def __init__(self,name):
            self.name
=name person_yuan=Person("yuan") person_egon=Person("egon") person_alex=Person("alex") person_list=[person_yuan,person_egon,person_alex] return render(request,"index.html",{"l":l,"dic":dic,"date":date,"person_list":person_list})
模版檔案:template:
<h4>{{s}}</h4>
<h4>列表:{{ l.0 }}</h4>  # 深度查詢(查詢列表中的第一個元素)  
<h4>列表:{{ l.2 }}</h4>
<h4>字典:{{ dic.name }}</h4>
<h4>日期:{{ date.year }}</h4>
<h4>類物件列表:{{ person_list.0.name }}</h4>
注意:句點符也可以用來引用物件的方法(無引數方法):
<h4>字典:{{ dic.name.upper }}</h4>

2.模版語法之過濾器

     固定語法:
{{obj|filter__name:param}}
     data
<p> {{ now|date:"Y-m-d"}}</p>   # now是datatime模組的datetime.now
    default

    如果一個變數是False或者為空,使用給定的,預設值。否則,使用變數的值。

{{ value|default:"nothing" }}
    length

   返回值的長度。它對字串和列表都起作用。例如:

{{ value|length }}

    如果 value 是 ['a', 'b', 'c', 'd'],那麼輸出是 4。

   slice
{{ value|slice:"2:-1" }}
   truncatechars

   如果字串字元多於指定的字元數量,那麼會被截斷。截斷的字串將以可翻譯的省略號序列(“...”)結尾。

{{ value|truncatechars:9 }}
   safe

Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,原因顯而易見,這樣是為了安全。但是有的時候我們可能不希望這些HTML元素被轉義,比如我們做一個內容管理系統,後臺新增的文章中是經過修飾的,這些修飾可能是通過一個類似於FCKeditor編輯加註了HTML修飾符的文字,如果自動轉義的話顯示的就是保護HTML標籤的原始檔。為了在Django中關閉HTML的自動轉義有兩種方式,如果是一個單獨的變數我們可以通過過濾器“|safe”的方式告訴Django這段程式碼是安全的不必轉義。比如:

value="<a href="">點選</a>"
{{ value|safe}}

   add

l = [100]
<p>{{ l.0|add:100}}</p>

   upper

<p>{{ info.name|upper}}</p>

3.模版語法之標籤

   標籤看起來像是這樣的:{% tag %}。標籤比變數更加複雜:一些在輸出中建立文字,一些通過迴圈活邏輯來控制流程,一些載入其後的變數將使用到的額外資訊到模版中。一些標籤需要開始和結束標籤(例如{% tag %}…標籤 內容 …{% endtag %})。

for標籤:遍歷每一個元素
可以利用{% for obj in list reversed %}反向完成迴圈。遍歷一個字典:
{% for key,val in dic.items %}
    <p>{{ key }}:{{ val }}</p>
{% endfor %}

迴圈序號可以通過{{forloop}}顯示,屬性如下

forloop.counter            The current iteration of the loop (1-indexed)
forloop.counter0           The current iteration of the loop (0-indexed)
forloop.revcounter         The number of iterations from the end of the loop (1-indexed)
forloop.revcounter0        The number of iterations from the end of the loop (0-indexed)
forloop.first              True if this is the first time through the loop
forloop.last               True if this is the last time through the loop

例子:

{% for key,val in dic.items %}
    <p>{{forloop.counter0}}     {{ key }}-{{ val }}</p>
{% endfor %}
for…empty:for 標籤帶有一個可選的{% empty %} 從句,以便在給出的組是空的或者沒有被找到時,可以有所操作。
{% for person in person_list %}
    <p>{{ person.name }}</p>

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}
if 標籤:{% if %}會對一個變數求值,如果它的值是“True”(存在,不為空,且不是boolean型別的false值),對應的內容塊會輸出。
{% if num > 100 or num < 0 %}
    <p>無效</p>
{% elif num > 80 and num < 100 %}
    <p>優秀</p>
{% else %}
    <p>湊活吧</p>
{% endif %}
with:使用一個簡單地名字快取一個複雜的變數,當你需要使用一個“昂貴的”方法(比如訪問資料庫)很多次的時候是非常有用的。
{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}
csrf_token:這個標籤用於跨站請求偽造保護
{% csrf_token %}  # 能第一次訪問伺服器就能發“POST”請求,寫在盒子內容程式碼第一行

4.自定義標籤和過濾器

1、在settings中的INSTALLED_APPS配置當前app,不然django無法找到自定義的simple_tag.
2、在app中建立templatetags模組(模組名只能是templatetags)
3、建立任意 .py 檔案,如:my_tags.py

from django import template
from django.utils.safestring import mark_safe
register = template.Library()   #register的名字是固定的,不可改變  
@register.filter
def filter_multi(v1,v2):
return  v1 * v2
<br>
@register.simple_tag
def simple_tag_multi(v1,v2):
    return  v1 * v2
<br>
@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

4、在使用自定義simple_tag和filter的html檔案中匯入之前建立的 my_tags.py

{% load my_tags %}

5、使用simple_tag和filter(如何呼叫)

-------------------------------.html
{% load xxx %}        
# num=12
{{ num|filter_multi:2 }} #24
{{ num|filter_multi:"[22,333,4444]" }}
{% simple_tag_multi 2 5 %}  引數不限,但不能放在if for語句中
{% simple_tag_multi num 5 %}

注意:filter可以用在if等語句後,simple_tag不可以

{% if num|filter_multi:30 > 100 %}
    {{ num|filter_multi:30 }}
{% endif %}

5.模版語法之繼承

Django模版引擎中最強大也是最複雜的部分就是模版繼承了。模版繼承可以讓您建立一個基本的“骨架”模版,它包含您站點中的全部元素,並且可以定義能夠被子模版覆蓋的 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。
在這個例子中, block 標籤定義了三個可以被子模版內容填充的block。 block 告訴模版引擎: 子模版可能會覆蓋掉模版中的這些位置。 下面是一個可能的子模版:

{% extends "base.html" %}

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

請注意,子模版並沒有定義 sidebar block,所以系統使用了父模版中的值。父模版的 {% block %} 標籤中的內容總是被用作備選內容(fallback)。
這種方式使程式碼得到最大程度的複用,並且使得新增內容到共享的內容區域更加簡單,例如,部分範圍內的導航。
這裡是使用繼承的一些提示:

  • 如果你在模版中使用 {% extends %} 標籤,它必須是模版中的第一個標籤。其他的任何情況下,模版繼承都將無法工作。
  • 在base模版中設定越多的 {% block %} 標籤越好。請記住,子模版不必定義全部父模版中的blocks,所以,你可以在大多數blocks中填充合理的預設內容,然後,只定義你需要的那一個。多一點鉤子總比少一點好。
  • 如果你發現你自己在大量的模版中複製內容,那可能意味著你應該把內容移動到父模版中的一個 {% block %} 中。
  • If you need to get the content of the block from the parent template, the variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.
  • 為了更好的可讀性,你也可以給你的{% endblock %} 標籤一個 名字 。例如:
{% block content %}
...
{% endblock content %}

在大型模版中,這個方法幫你清楚的看到哪一個  {% block %} 標籤被關閉了。

  • 不能在一個模版中定義多個相同名字的 block 標籤。