django學習筆記-模板層
模板層
將Python嵌入到HTML中。
模板簡介
將HTML硬解碼到檢視並不是那麼完美原因如下:
- 對頁面設計時也需要對python程式碼進行相應的修改,模板可以不就行python程式碼修改的情況下變更設計。
- 編寫python和HTML設計是兩項不同的工作,應該明確分工。
- 兩項同時進行效率最高。
模板:HTML程式碼+模板語法
def current_time(req): # ================================原始的檢視函式 # import datetime # now=datetime.datetime.now() # html="<html><body>現在時刻:<h1>%s.</h1></body></html>" %now # return HttpResponse(html) #另一種寫法(推薦) import datetime now=datetime.datetime.now() return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})
模板語法的重點:
變數:{{ 變數名 }}
1.深度查詢用句點符
2.過濾器
標籤:{% %}
二、模板語言的註釋
{# this won't be rendered #} 單行註釋
註釋多行使用comment標籤
三、模板語法之變數
在django模板中遍歷複雜資料結構的關鍵是句點字元,語法:{{ 變數名 }}。變數類似於python中的變數。
變數的命名包括任何字母數字以及下劃線("_")的組合。點(".")也有可能會在變數名中出現,不過它有特殊的含義。最重要的是,變數名稱中不能有空格或標點符號。
views.py:
name='abc' age=18 li=[1,2,'3','4'] dic={'name':'abc','age':18,''li:[1,2,4]} def test(): #函式 print('abc') return 'abchahahah' class Person(): def __init__(self,name,age) self.name=name self.age=age def get_name(self): return self.name @classmethod def cls_test(cls): return 'cls' @staticmethod def static_test(): return 'static' --------- # 模板裡不支援帶引數 def get_name_cs(self,ttt): return self.name ---------- zfj=Person('zfj',18) qer=Person('qwe',28) person_list=[zfj,qwe]
html:
相當於print了該變數
<p>字串:{{ name }}</p>
<p>數字:{{ age }}</p>
<p>列表:{{ li }}</p>
<p>元祖:{{ tu }}</p>
<p>字典:{{ dic }}</p>
<p>函式:{{ test }}</p> {#只寫函式名:相當於函式名(),返回函式執行結果#}
<p>物件:{{ zfj }}</p> {#物件記憶體地址#}
深度查詢:
<p>列表第1個值:{{ ll.0 }}</p> <p>列表第4個值:{{ ll.3 }}</p> <p>字典取值:{{ dic.name }}</p> <p>字典取列表值:{{ dic.li }}</p> <p>物件取資料屬性:{{ zfj.name }}</p> <p>物件取繫結給物件的函式屬性:{{ zfj.get_name }}</p> <p>物件取繫結給類的函式屬性:{{ zfj.cls_test }}</p> <p>物件取靜態方法:{{ zfj.static_test }}</p>
四、模板語言之過濾器
語法:
{{變數名|過濾器名稱:屬性值}}
過濾器可以“連結”,一個過濾器的輸出應用於下一個過濾器{{text|escape|linebreaks}}
,先轉移文字內容,然後把文字轉成<p>
標籤。
注:過濾器引數包含空格,必須用引號抱起來。
1.過濾器總覽
過濾器 | 說明 |
---|---|
add | 加法 |
addslashes | 新增斜槓 |
capfirst | 首字母大寫 |
center | 文字居中 |
cut | 切除字元 |
date | 日期格式化 |
default | 設定預設值 |
default_if_none | 為None設定預設值 |
dictsort | 字典排序 |
dictsortreversed | 字典反向排序 |
divisibleby | 整除判斷 |
escape | 轉義 |
escapejs | 轉義js程式碼 |
filesizeformat | 檔案尺寸人性化顯示 |
first | 第一個元素 |
floatformat | 浮點數格式化 |
force_escape | 強制立刻轉義 |
get_digit | 獲取數字 |
iriencode | 轉換IRI |
join | 字元列表連結 |
last | 最後一個 |
length | 長度 |
length_is | 長度等於 |
linebreaks | 行轉換 |
linebreaksbr | 行轉換 |
linenumbers | 行號 |
ljust | 左對齊 |
lower | 小寫 |
make_list | 分割成字元列表 |
phone2numeric | 電話號碼 |
pluralize | 複數形式 |
pprint | 除錯 |
random | 隨機獲取 |
rjust | 右對齊 |
safe | 安全確認 |
safeseq | 列表安全確認 |
slice | 切片 |
slugify | 轉換成ASCII |
stringformat | 字串格式化 |
striptags | 去除HTML中的標籤 |
time | 時間格式化 |
timesince | 從何時開始 |
timeuntil | 到何時多久 |
title | 所有單詞首字母大寫 |
truncatechars | 截斷字元 |
truncatechars_html | 截斷字元 |
truncatewords | 截斷單詞 |
truncatewords_html | 截斷單詞 |
unordered_list | 無序列表 |
upper | 大寫 |
urlencode | 轉義url |
urlize | url轉成可點選的連結 |
urlizetrunc | urlize的截斷方式 |
wordcount | 單詞計數 |
wordwrap | 單詞包裹 |
yesno | 將True,False和None,對映成字串‘yes’,‘no’,‘maybe’ |
2.常用過濾器
default
如果變數是false或者為空,則使用給定的預設值。
{{ value|default:'nothing'}}
length
返回值的長度,對字串和列表都起作用
{{ value|length}}
如果value是[1,2,3,4]
,那麼輸出是4
filesizeformat
將值格式化成'人類可讀的'檔案尺寸。例如:
{{1024|filesizeformat}} 輸出為1kb
date
如果value=datetime.datetime.now()
{{ value|date:"Y-m-d"}}
slice
切片
{{ name|slice:'0:3:3' }}
truncatechars
如果字串多餘指定字元數量,多餘會被截斷,替換成("...")結尾。
{{ value|truncatechars:9}}
safe
Django模板為了安全預設會對HTML標籤和js等語法標籤進行轉義,有時候我們不希望這些元素被轉義,可以通過設定過濾器。
script="'<script>alert(111)</script>"
{{ script|safe }}
五、模板之標籤
一些在輸出中建立文字,一些通過迴圈或邏輯來控制流程,一些載入其後的變數將使用到的額外資訊到模版中。一些標籤需要開始和結束標籤 (例如{% tag %} ...標籤 內容 ... {% endtag %})。
{% tag %}
1.內建標籤總覽
標籤 | 說明 |
---|---|
autoescape | 自動轉義開關 |
block | 塊引用 |
comment | 註釋 |
csrf_token | CSRF令牌 |
cycle | 迴圈物件的值 |
debug | 除錯模式 |
extends | 繼承模版 |
filter | 過濾功能 |
firstof | 輸出第一個不為False的引數 |
for | 迴圈物件 |
for … empty | 帶empty說明的迴圈 |
if | 條件判斷 |
ifequal | 如果等於 |
ifnotequal | 如果不等於 |
ifchanged | 如果有變化,則.. |
include | 匯入子模版的內容 |
load | 載入標籤和過濾器 |
lorem | 生成無用的廢話 |
now | 當前時間 |
regroup | 根據物件重組集合 |
resetcycle | 重置迴圈 |
spaceless | 去除空白 |
templatetag | 轉義模版標籤符號 |
url | 獲取url字串 |
verbatim | 禁用模版引擎 |
widthratio | 寬度比例 |
with | 上下文變數管理器 |
2.常用標籤
for標籤
遍歷每一個元素
{% for person in person_list %}
<p>{{ person }}</p>
{% end for%}
遍歷一個字典:
{% for k,v in dic.items %}
<p>{{ k }}:{{ v }}</p>
下面是Django為for標籤內建的一些屬性,可以當作變數一樣使用{{ }}
在模版中使用。
- forloop.counter:迴圈的當前索引值,從1開始計數;常用於生成一個表格或者列表的序號!
- forloop.counter0:迴圈的當前索引值,從0開始計數;
- forloop.revcounter: 迴圈結束的次數(從1開始)
- forloop.revcounter0 迴圈結束的次數(從0開始)
- forloop.first:判斷當前是否迴圈的第一次,是的話,該變數的值為True。我們經常要為第一行加點特殊的對待,就用得上這個判斷了,結合if。
- forloop.last:如果這是最後一次迴圈,則為真
- forloop.parentloop:對於巢狀迴圈,返回父迴圈所在的迴圈次數。某些場景下,這是個大殺器,能解決你很多頭疼的問題。
for...empty
for標籤帶有一個可選的{% empty %}
從句,在給出的組是空的或者沒有被找到時執行的操作
注:迴圈的物件是空,才會走到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 %}
注:在if標籤中使用括號是錯誤的語法,這點不同於Pythonif語句支援 ,優先順序可以使用if巢狀。if支援and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷。
with
使用一個簡單地名字快取一個複雜的變數,當你需要使用一個“昂貴的”方法(比如訪問資料庫)很多次的時候是非常有用的
{% with total=business.employees.count %}
{{ total }} employee{{ total|pluralize }}
{% endwith %}
六、自定義標籤和過濾器
Django為我們提供了自定義的機制,可以通過使用Python程式碼,自定義標籤和過濾器來擴充套件模板引擎,然後使用{% load %}標籤。
(一)、前置步驟
在settings中的
INSTALLED_APPS
配置當前app,不然django無法找到自定義的simple_tag.在app中新建一個
templatetags
包(名字固定),與views.py、models.py等檔案在同一目錄下注:新增templatetags包後,需要重新啟動伺服器,然後才能在模板中使用標籤或過濾器
建立任意 .py 檔案,如:my_tags.py
要在模組內自定義標籤,首先,這個模組必須包含一個名為register的變數,它是template.Library的一個例項,所有的標籤和過濾器都是在其中註冊的。 所以把如下的內容放在你的模組的頂部:
from django.template import Library
register = Library()
templatetags包中放多少個模組沒有限制。只需要記住{% load xxx %}
將會載入給定模組名中的標籤/過濾器,而不是app中所有的標籤和過濾器。
(二)、自定義模板過濾器
1.編寫過濾器
自定義過濾器就是一個帶有一個或兩個引數的python函式
注:函式的第一個引數是要過濾的物件,第二個是自定義引數,函式一共只能有兩個引數。
- 變數的值:不一定是字串形式
- 可以有一個初始值,或者不需要這個引數
例子:
def filter_multi(v1,v2):
return v1 * v2
2.註冊過濾器
定義好過濾器函式之後,需要註冊,方法是呼叫register.filter
register.filter('filter_multi',filter_multi)
Library.filter()
方法需要兩個引數:
- 過濾器的名稱:一個字串物件
- 編譯的函式 :你剛才寫的過濾器函式
還可以把register.filter()
用作裝飾器,以如下的方式註冊過濾器:
@register.filter(name='yyy')
注:沒有宣告name引數,Django將使用函式名作為過濾器的名字。
3.過濾器的使用方法
在要使用自定義過濾器的模板中匯入建立的py檔案。
語法:
{% load 檔名 %}
要使用的地方。
{{'abc'|yyy:'qwe'}}
結果輸出abcqwe
(三)、自定義模板標籤
除了裝飾器,其它步驟與自定義過濾器相似。
@register.simple_tag()
過濾器只能有兩個引數,自定義標籤可以傳多個值,空格傳值。
注:過濾器可以用在if判斷中,標籤不能
七、模板繼承
模版繼承可以讓您建立一個基本的“骨架”模版,它包含您站點中的全部元素,並且可以定義能夠被子模版覆蓋的 blocks 。
1.模板匯入
語法:{% include'模板名稱' %}
如:{% include 'base.html' %}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css"/>
<title>{% block title %}My amazing site{% 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>
它定義了一個可以用於兩列排版頁面的簡單HTML骨架。“子模版”的工作是用它們的內容填充空的blocks。
2.子模板中使用
語法:
{% block名字 %}
子模板的內容
{% endblock %}
{% block content %}
<p>這是子的區域</p>
<p>這是子的區域</p>
<p>這是子的區域</p>
<p>這是子的區域</p>
{% endblock content%}
注:
- 如果在模板中使用
{% extends %}
標籤,它必須是模板中的第一個標籤 - 在base模板中設定越多的
{% block %}
標籤越好,子模板不必定義全部父模板中的blocks - 如果發現有大量的模板存在重複內容,可以定義在父模板的{% block %}中。
- 不能再一個模板中定義多個相同名字的block標籤
- 為了更好的可讀性,可以給
{% endblock %}
設定一個名字
{% block content %}
{% endblock content%}
八、靜態檔案相關
寫死靜態檔案:
使用 static標籤函式:
{% load static %} <link rel="stylesheet" href="{% static 'css/mycss.css' %}">
使用get_static_prefix 標籤
{% load static %} <link rel="stylesheet" href="{% get_static_prefix %}css/mycss.css">