Django框架——基礎之模板系統(template文件夾)

---恢復內容開始---css

1. 經常使用語法

須要記住兩組特殊符號:{{  }}  和 {%  %}html

在運用到變量的時候使用{{  }},若是是跟邏輯相關的話就使用{%  %}。python

在Django模板(template)中,會使用到的{{  }}  和 {%  %}寫法,在專業中就稱之爲Django的 「 模板語言 」 django

2. 變量

在Django模板中,使用的變量的時候,就是用這個格式:{{ 變量名 }}。安全

在template模板引擎遇到一個變量的時候,它自動根據python後臺中的views模塊提供的相關數據,計算出這個變量的結果,並用這個結果替換掉它本身。app

變量命名:命名規則包含(字符、數字、下劃線)的組合。函數

注意:變量的名稱必定不能含有空格、標點符號。oop

點(.)在模板語言中有特殊的含義。當模版系統遇到點("."),它將以這樣的查詢優先級:spa

第一:字典查詢(Dictionary lookup)code

第二:屬性或方法查詢(Attribute or method lookup)

第三:數字索引查詢(Numeric index lookup)

注意事項:

  1. 若是計算結果的值是可調用的,它將被無參數的調用。 調用的結果將成爲模版的值。
  2. 若是使用的變量不存在, 模版系統將插入 string_if_invalid 選項的值, 它被默認設置爲'' (空字符串) 。

變量的使用寫法:

{# 取list列表中的第一個參數 #}
{{ list.0 }}

{# 取d字典中key的值 #}
{{ d.name }}

{# 取對象的name屬性 #}
{{ person_list.0.name }} {# (大白話:人對象的列表  第一我的對象 的 名字)," . "點跟"的」有些相似#}
{# .操做只能調用不帶參數的方法 #} {{ person_list.0.eat }}

注意:若是是調用方法的話,後面也不能帶括號()。

3. Filters(過濾器)

在Django的模板語言中,經過使用過濾器來改變變量的顯示(結果)。

過濾器的語法:{{ name|filter_name:參數 }}。注意:使用管道符 」 | 「 name就是變量的結果,其實就是變量名。

例如:在模板中的一個變量使用以下{{ name|lower}}會將name變量經過length過濾(操做)以後再顯示它的值。lower在這裏的做用是將文本全都變成小寫。

注意事項:

  1. 過濾器支持「鏈式」操做。即一個過濾器的輸出做爲另外一個過濾器的輸入 。
  2. 過濾器能夠接受參數。例如:{{ sss|truncatewords:30 }},這將顯示sss的前30個詞。
  3. 過濾器參數包含空格的話,必須用引號包裹起來。好比使用逗號和空格去鏈接一個列表中的元素,如:{{ list|join:', ' }}
  4. '|'左右沒有空格沒有空格沒有空格

3.1 default

例如:{{ name|default:"not found" }}

若是變量name的值是false或者爲空或者不存在,該處自動被默認值not found字符串代替,或者說此處的變量名的值自動爲"not found" 。

3.2 length

例如:{{ name|length}}

返回變量name的值的長度,做用於字符串和列表。

若是上面的name=[1, 2, 3, 4, 5, 6],那上面獲得的值就是6.

3.3 filesizeformat

 例如:{{ name|filesizeformat }}

將name的值進行格式化,也就是說,將一個文件的大小進行自動轉換成爲,咱們平時生活中可以理解的格式!(例如:「 20MB 」,「 20KB 」,「 20GB 」 等等)

若是name的值是123456789,輸出的將會是117.7MB。

3.4 slice

 例如:{{ name_list|slice:":2" }

返回列表的一部分。也就是切片,與Python的列表切片相同的語法。

若是name_list = ["張三", "李四", "王五", "老六"],那上面的結果將會獲得["張三", "李四"]

3.5 date

根據給定格式對一個日期變量進行格式化。

可用的格式字符串:

格式化字符 描述 示例輸出
a 'a.m.'或'p.m.' 'a.m.'
A 'AM'或'PM' 'AM'
b 月份,文字形式,3個字母,小寫。 「jan」
B 未實現。  
c ISO 8601格式 2008-01-02T10:30:00.000123+02:00
d 月的日子,帶前導零的2位數字。 '01'到'31'
D 周幾的文字表述形式,3個字母。 'Fri'
e 時區名稱 '','GMT','-500','US/Eastern'等
E 月份,分地區。  
f 時間 '1','1:30'
F 月,文字形式。 'January'
g 12小時格式,無前導零。 '1'到'12'
G 24小時格式,無前導零。 '0'到'23'
h 12小時格式。 '01'到'12'
H 24小時格式。 '00'到'23'
i 分鐘 '00'到'59'
I 夏令時間,不管是否生效。 '1'或'0'
j 沒有前導零的月份的日子。 '1'到'31'
l 星期幾,完整英文名 'Friday'
L 布爾值是不是一個閏年。 True或False
m 月,2位數字帶前導零。 '01'到'12'
M 月,文字,3個字母。 「Jan」
n 月無前導零。 '1'到'12'
N 美聯社風格的月份縮寫。 'Jan.','Feb.','March','May'
o ISO-8601周編號 '1999'
O 與格林威治時間的差,單位小時。 '+0200'
P 時間爲12小時 '1 am','1:30 pm','midnight','noon','12:30 pm'>
r RFC 5322格式化日期。 'Thu, 21 Dec 2000 16:01:07 +0200'
s 秒,帶前導零的2位數字。 '00'到'59'
S 一個月的英文序數後綴,2個字符。 'st','nd','rd'或'th'
t 給定月份的天數。 28 to 31
T 本機的時區。 'EST','MDT'
u 微秒。 000000 to 999999
U 自Unix Epoch以來的秒數(1970年1月1日00:00:00 UTC)。  
w 星期幾,數字無前導零。 '0'(星期日)至'6'(星期六)
W ISO-8601週數,週數從星期一開始。 1,53
y 年份,2位數字。 '99'
Y 年,4位數。 '1999'
z 一年中的日子 0到365
Z 時區偏移量,單位爲秒。 -43200到43200

例如:{{ name|date:"Y-m-d H:i:s"}}

若是name是一個datetime對象,好比datetime.datetime.now(),輸出將是字符串 ' 2017-08-30 11:08:29 ' 。

能夠將date與time過濾器結合使用,以呈現datetime值的完整表示形式。 例如:

{{ value|date:"D d M Y" }} {{ value|time:"H:i" }}

3.6 safe

 例如:

  {{ name|safe }}

將字符串標記爲安全,不須要轉義。

詳解:

  Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統,後臺添加的文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本,若是自動轉義的話顯示的就是保護HTML標籤的源文件。爲了在Django中關閉HTML的自動轉義有兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的不i必轉義。

若是這裏的name的值爲name= "<a href='http://www.baidu.com/'>點我進入百度</a>"。這個時候,這裏的點我將會成爲一個定向百度連接的超級連接,也就是說只要點擊" 點我進入百度 "就能夠跳轉到百度頁面!

3.7 truncatechars

例如:
  {{ name|truncatechars:9 }}
參數:截斷以後剩下的字符數

若是字符串包含的字符總個數多於指定的字符數量,那麼會被截斷掉後面的部分。截斷的字符串將以「...」結尾,注意結尾中的 」...「 算三個字符

若是這裏的name的值是 「my name is xxxx」,那上面輸出的結果是:my nam...

3.8 truncatewords

例如:

  {{ name|truncatewords:2 }}

 在必定數量的字數後截斷字符串。與truncatechars不一樣的是,這個以字的個數計數而不是字符計數。截斷的字符串將以「...」結尾,注意結尾中的 」...「 在這裏不算三個字符了

若是這裏的name的值仍是「my name is xxxx」 ,那上面輸出的結果是:my name...

3.9 cut

例如:

{{ name|cut:"," }}

移除name中全部的與給定參數相同的字符串。這裏的是意思是:移除name的值中,存在的逗號 」,"。

若是name的值是爲「my,name,is,xxxx」,輸出將爲"Smynameisxxxx"。

3.10 join

例如:{{ name|join:"//" }} 

使用字符串鏈接列表,相似Python的str.join(list)

若是上面的name=["aa", "bb", "cc"],在帶入上面變量以後獲得的結果就是:aa//bb//cc。

注意:若是name是字典的話,例如:name={"aaa": 111, "bbb": 222},結果爲key的連接,即獲得的結果爲:aaa//bbb

3.11 timesince

傳入的時間對象(blog_date)跟當前的時刻的時間(comment_date)的一個時間差,用於寫多長時間以前。說白了,這個就是計算兩個時間的時間差(comment_date — blog_date)。

時間的差值被Django自動換算,能夠表示(例如,「4天,6小時」)。

例如:{{ blog_date|timesince:comment_date }}

3.12 timeuntil

相似於timesince,它測量從如今開始直到給定日期或日期時間的時間。例如,若是今天是2006年6月1日,而conference_date是2006年6月29日,則{{ conference_date | timeuntil }}將返回「4 weeks」。

可選參數是一個包含用做比較點的日期變量。若是from_date爲2006年6月22日,則如下內容將返回「1 weeks」:

{{ conference_date|timeuntil:from_date }}

3.13 自定義filter

自定義的filter(過濾器)能夠分爲三大步驟:首先是前期步驟,而後是編輯filter過濾器,最後是使用自定義filter過濾器

首先,自定義filter前期步驟:

  1.  在app中新建一個templatetags名字固定,不能變,只能是這個),和views.py、models.py等文件處於同一級別目錄下。這是一個python包!因此,必定不要忘記這個包的裏面是要有__init__.py文件的,由於__init__.py文件是以使得該目錄能夠做爲Python的包的條件。

  2.  在添加templatetags包後,須要從新啓動項目,而後才能在模板中使用標籤或過濾器。

  3.  在templatetages包裏,建立自定義過濾器的模塊。

    a    將你自定義的標籤和過濾器將放在templatetags包下的一個模塊裏。

    b    這個模塊的名字是後面載入標籤時使用的標籤名,因此要謹慎的選擇名字以防與其餘應用下的自定義標籤和過濾器名字衝突,固然更不能與Django內置的衝突。

    假設你自定義的標籤/過濾器在一個名爲app01_myfilter.py的文件中,那麼你的app目錄結構看起來應該是這樣的:

app01/
    __init__.py
    models.py
    templatetags/        # templatetags包
        __init__.py
        app01_myfilter.py    # 建立存放自定義filter(過濾器)的文件
    admin.py
    apps.py
    views.py

而後,是編寫自定義filter過濾器:

  app01_myfilters.py文件代碼以下:步驟是  1  >>  2  >>  3

# 1.  首先須要引入template模塊,並建立一個library註冊對象
from django import template
register = template.Library()


# 2.  接着纔是正式編輯filter

@register.filter(name="addsb")    # 3.  註冊filter(filter的別名爲addsb):寫好下面的自定義filter函數後,須要註冊過濾器,用裝飾器函數形式便可
def add_sb(value):                        # 定義不帶參數的自定義filter函數
    return "{} SB.".format(value)    

@register.filter(name="add_str")      # 3.  註冊filter(filter的別名爲add_str):同上   
def add_str(value, arg):        # 定義帶一個參數的自定義filter
    return "{} {}.".format(value, arg)

#  注意:第一個參數(value)永遠是管道符前面那個變量,第二個之後纔是參數    

最後,是使用自定義filter過濾器

  1.   須要在template模塊下面的模板中,引入自定義過濾器的文件模塊以下:

    {% load app01_myfilters %}

  2.  結合變量使用自定義的filter過濾器  

    <p>不帶參數自定義filter:{{ myname|addsb }}</p>

    <p>帶參數的自定義filter:{{ myname|addstr:"牛逼" }}</p>

        解析:管道符 」 | 「 的左邊的myname是views.py模塊提供的變量,右邊的addsb是自定義的filter過濾器,而冒號 」 : 「的右邊則是本身寫的參數。

    若是myname的值爲 myname = "my name is" 

    帶入上面的的自定義filter過濾器後結果以下:

      不帶參數自定義filter:my name is sb.

      帶參數的自定義filter:my name is 牛逼.

建立自定義的filter過濾器簡單步驟:

  第一.  首先建立templatetags python包,接着從新啓動項目,最後建立用於存放自定義filter過濾器的.py文件

  第二.  首先引入django下面的template模塊,接着編寫自定義的filter過濾器函數,最後使用裝飾器的形式註冊過濾器函數,並經過name定義過濾器的名稱(過濾器函數的別名)

  第三.  首先,在模板語言中,使用{% load 自定義filter名稱%}引入自定義filter過濾器,接着在引入的下面開始使用過濾器便可。

 

3.14

 

3.15

 

3.16

 

4. Tags(邏輯標籤)

4.1 for循環

普通for循環

<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% endfor %}
</ul>

for循環可用的一些參數:

 

Variable Description
forloop.counter 當前循環的索引值(從1開始)
forloop.counter0 當前循環的索引值(從0開始)
forloop.revcounter 當前循環的倒序索引值(從1開始)
forloop.revcounter0 當前循環的倒序索引值(從0開始)
forloop.first 當前循環是否是第一次循環(布爾值)
forloop.last 當前循環是否是最後一次循環(布爾值)
forloop.parentloop 本層循環的外層循環

for ... empty for循環

當下面的user_list裏面的內容爲空,或者user_list根本不存在的時候,for循環會自動跳轉到empty程序塊,而且執行(若是是下面的話就是獲得:空空如也)。
複製代碼
<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% empty %}
    <li>空空如也</li>
{% endfor %}
</ul>
複製代碼

 

4.2 if判斷

 

if……else  語句

{% if user_list|length > 5 %}
    用戶數超過5人
{% else %}     
    用戶數小於等於5人,或沒有用戶
{% endif %}

if……elif……else語句

複製代碼
{% if user_list %}
  用戶人數:{{ user_list|length }}
{% elif black_list %}
  黑名單數:{{ black_list|length }}
{% else %}
  沒有用戶
{% endif %}

if語句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷。

4.3 with語句

 當一個變量很長很複雜的時候,定義一箇中間變量,多用於給一個複雜的變量起別名。

例如一個名字的列表name_list2 = [['張三0', '李四0', '王五0'], ['張三1', ['張三1.1', '李四1.1', '王五1.1'], '王五1']]
當咱們要取 " 李四1.1 " 的時候,就是 " name_list2.1.1.1 "這個時候就以爲 name_list2.1.1.1比較長,
而在某個模板語言的某個程序塊中會一直用到這個,因此咱們須要給它起一個別名,主要目的是爲了方便操做

起別名的方法有一下兩種方式

注意:等號左右不要加空格。

 
{% with total=name_list2.1.1.1%} 
  {{ total }} with語法{{ total|pluralize }}
{% endwith %}
 

 
{% with name_list2.1.1.1 as total %} 
  {{ total }} with語法{{ total|pluralize }}
{% endwith %}

4.4 csrf_token

這個標籤用於跨站請求僞造保護。

在頁面的form表單裏面寫上{% csrf_token %}

4.5 註釋

{# 註釋內容... #}

4.6 模板語言使用注意事項

1. Django的模板語言不支持連續判斷,即不支持如下寫法:

{% if a > b > c %}
...
{% endif %}

 

2. Django的模板語言中屬性的優先級大於方法

def xx(request):
    d = {"a": 1, "b": 2, "c": 3, "items": "100"}
    return render(request, "xx.html", {"data": d})

如上,咱們在使用render方法渲染一個頁面的時候,傳的字典d有一個key是items而且還有默認的 d.items() 方法,此時在模板語言中:

{{ data.items }}

默認會取d的items key的值。

5. 母版(模板)

 注意:咱們一般會在母板中定義頁面專用的CSS塊和JS塊,方便子頁面替換。

 

5.1繼承母版

 在子頁面中的第一行代碼必須使用下面的語法來繼承母版,其中base.html是母版文件!

{% extends 'base.html' %}

5.2母版與繼承母版的注意事項:

1.子頁面中的繼承母版的語句必定要放在第一行!

2.{% extends 'base.html' %},繼承語法中的母版名稱位置,是有引號的

3.在母版文件base,html中,是會定義不少塊(block)的,可是咱們會固定的另外定義page-js和pafe-css兩個塊

4.在view.py中的對應關係的函數,返回的是子頁面的!!而不是母版哦!!!

 

5.3塊(block)

 在母版中使用塊的語法定義:{% block page-main %} …………{% endblock % }。塊的名字:page-main

 

例如:這條語句已經在木板文件中定義了。那接下這子頁面中的應用以下:

//子頁面中對應母版的塊的定義
{% block page-main %}     //首尾語法與母版中如出一轍

<div class="content">
   <
p>  我想寫一首詩<br/></p> <p>  記錄我對你的思念</p> <p>  我想寫一首詩</p> <p>  記下這痛苦的瞬間</p> <p>  我想寫一首詩</p> <p>  記住這慘痛的教訓</p> <p>  我想唱一曲歌</p> <p>  唱出我思念你時的情懷</p> <p>  我想唱一首歌</p> <p>  唱到我幻想的浪漫深處</p> <p>  我想唱一支歌</p> <p>  歌頌我對你的癡情</p> <p>  惋惜怯懦的我哽咽着哭泣,始終沒拿起也沒放棄</p> <p>  春光撫摸着個人愛意</p> <p>  夏日打擊着個人衝動</p> <p>  秋風嘲諷着個人深情</p> <p>  冬雪將個人軀幹冰封</p> <p>  我無力掙扎,掙扎,掙扎</p> <p>  直到春暖融盡這刺骨的冰霜</p> <p>  夏炎炙烤着個人肢體</p> <p>  秋愁撕裂着個人心府</p> <p>  冬魔蠶食着個人生命</p> <p>  幾番風雨,幾多癡迷,幾度春秋……</p> <p>  啊!彩虹,那麼近,那麼亮</p> <p>  別告訴我那是地獄之火,我要去天堂;</p> <p>  別對我說那是天堂之光</p> <p>  錯了,我將留在這慘痛的人間!</p> <p>  去地獄的是佛,上天堂的是仙,我是人,卻不肯留在虛僞的凡間</p> <p>  我一直走,走,走</p> <p>  沒有盡頭,決不回頭,只期盼有一天能碰頭……</p> </div> {% endblock %} //首尾語法與母版中如出一轍

5.4 爲何要有模板和繼承?

把多個頁面公用的部分提取出來,放在一個 母版 裏面。
其餘的頁面只須要 繼承 母版就能夠了。

5.5 使用模板的基本步驟:

1.把全部THML網頁的公用(相同部分)提取出來,一同放到母版文件中,(通常來講母版文件的命名都是base.html)

2.在base.html中,經過塊的語法定義將來子頁面中會存在的塊,注意塊名必定要有意義

3.在子頁面的第一行必定要先繼承母版:{% extends 'base.html' %}

4.子頁面的編輯:子頁面中想要展現的內容要放到塊的語法當中,例如:{% block page-main %}  ……html代碼……{% endblock %},注意block(塊)名要正確指定母版中的相應位置才行!!

6. 組件

 爲了更好的體現代碼的複用性,咱們能夠將全部html頁面中經常使用的功能代碼塊提取出來,例如:導航條、頁尾信息等固定的重複的代碼單獨的保存到單獨的文件中,造成一個獨立的功能模塊,這就是組件。當咱們在建立新的頁面的時候,正好須要使用這些功能的時,就能夠隨時經過特定語法導入組件的文件就能夠就能夠了!!!

其實組件就是一個帶有特定的固定的功能的html文件而已,‘組件’只是一個名詞一個稱呼而已!

導入組件的語法:

{% include 'nav.html' %}      // 假設  nav.html 是導航的代碼,那經過這個導入語法,就能夠把導航裏面的代碼引入到頁面當中了

 

7. 靜態文件相關

 

7.1 {% static %}

引用CSS文件時使用:

{% load static %}
<img src="{% static "mystyle.css" %}" />

引用JS文件時使用:

{% load static %}
<script src="{% static "mytest.js" %}"></script>

某個文件多處被用到能夠存爲一個變量(起別名

{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>
注意:static是Django內置的一個模塊方法,由於,static能夠從配置文件(setting.py)中的  STATIC_URL = '/static/'  和 STATICFILES_DIRS = []找到對應靜態文件所在路徑。
這樣作有什麼好處呢?例如:一個模板中引入一個css文件的方法爲:
<link rel="stylesheet" href="/static/fontawesome/css/font-awesome.min.css">

你們是否是覺得上面這條引入css語句中的 「 static 」 直接是,項目文件中static文件呢?其實不是的!!!!!!

其實這個static是 STATIC_URL = '/static/' 中的static,而真實的路徑是由 STATICFILES_DIRS = [] 裏面的路徑自動拼接而獲得的!

7.2 {% get_static_prefix %}

{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />

或者

{% load static %}
{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />
 

get_static_prefix:是一個能夠獲取到 ' /static/ '字符串的函數,經過獲取到的' /static/ '字符串手動拼接一條路徑!

8. tag

8.1 simple_tag

和自定義filter相似,只不過接收參數的形式更加靈活


1.首先,跟自定義的filter同樣,須要在「app01項目文件夾」建立一個存放simple_tag的py文件,能夠命名爲app01_mytag.py

 

2.第二,app01_mytag.py編輯,跟自定義的filter同樣,須要引入template,以下:

  from django import template   register = template.Library()

 

3.第三,app01_mytag.py編輯,註冊register中simple_tag裝飾器,以下:

    @register.simple_tag(name="myjoin") def myjoin(arg1, arg2, arg3): return "{} + {} + {}".format(arg1, arg2, arg3)

 

4.第四,模板文件使用自定義的simple_tag

    {% load app01_mytag %}        #先加載,存放自定義simple_tag的py文件模塊 {% myjoin "aa" "bb" "cc" %}     #正式使用裝飾器,語法格式:{% 函數名或者註冊的時候起的別名 參數1 參數2 參數3…… %}

 

5.結果,result >> aabbcc

 

8.2 inclusion_tag

更多的時候用於返回html代碼片斷,

註冊的時候跟自定義filter和simple_tag的同樣。

1.首先,須要在「app01項目文件夾」建立一個存放inclusion_tag的py文件,能夠命名爲app01_mytag_inclu.py。或者自定義的inclusion_tag函數和simple_tag一塊兒放在同一文件

2.第二,app01_mytag_inclu.py編輯,一樣須要引入template,以下:

  from django import template   register = template.Library()

 

3.第三,app01_mytag_inclu.py編輯,一樣是須要註冊,但這裏註冊是的inclusion_tag,以下:

@register.inclusion_tag( 'result.html' ) def foo_result(n):   n = 1 if n < 1 else int(n)   data = ["第{}項".format(i) for i in range(1, n+1)]   return {"data": data}

 

4.第四,須要將第三步的結果引入到result.html,進行字符串的替換以後,獲得的html代碼片斷,纔會返回給使用inclusion_tag的模板
result.html代碼:

<ul> {% for choice in data %}   <li>{{ choice }}</li> {% endfor %} </ul>


5.第五,模板文件使用自定義的inclusion_tag

{% load app01_mytag_inclu %}    # 加載inclusion_tag所在的文件模塊
{% foo_result 10 %}    # 使用裝飾器,語法格式:{% 函數名 參數1 參數2 …… %}
相關文章
相關標籤/搜索