一.模板路徑的查找
1-查找順序
(1)首先查找模板設置路徑:項目文件夾,settings.py中的TEMPLATES裏面的DIRS,DIRS的值是個列表,裏邊能夠存放多個路徑,django項目會在這個列表裏自動從前日後找】
(2)接着去看APP_DIRS裏,判斷它的值,若是這個值爲True(默認爲True),則django會到一樣是項目文件夾中的settings.py中的INSTALLED_APPS(註冊了的app)中,依次去找,這也是個列表,查找順序從上到下
因此也能夠在app目錄下存放模板:例如最上面加一行'teacher.apps.TeacherConfig'來註冊這個app,或者能夠直接簡寫爲‘teacher’
這樣django會去teacher這個app的文件夾中,去尋找有沒有templates(模板),這樣在app中若是有templates文件夾,也能夠找到了,
注意app中的模板文件夾必須叫templates,否則找不到;項目根目錄中的模板文件夾能夠隨便起名
集中存放在項目文件夾下的templates文件夾裏的某app文件夾下的模板,相應的視圖函數想用這個模板,返回的路徑要寫'app名/模板名',好比return render(request,‘app1/html2.html’)
在相應app的視圖函數中,return render(request,‘html2.html’)路徑直接寫html模板文件名稱就能夠,不須要app名了。php
settings中css
INSTALLED_APPS = [ 'students.apps.StudentsConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
視圖函數中html
def index(request): return render(request, 'html_student_index.html')
2-兩種方案 優先級,DIRS裏的路徑優先級高於INSTALLED_APPS,一種是集中存放一種是分散在app中
(1)集中存放,方便管理,方便繼承,通常作大項目,須要集中管理,部署,會把模板集中存放
(2)分散在app中,是app能夠複用的時候,複用,一個app能夠被用於多個項目
3-爲何要在集中存放的tempaltes裏面再套一層
** 只要找到一個符合的模板,就返回,
1)不一樣app若是有同名的模板,前面的會覆蓋後面的,因此要把每一個app的模板分開放,這樣文件名加上相對路徑,就不會重複了,也便於管理後期查找
2)由於集中存放的優先級高,不加一層目錄的話,渲染模板也是render(request,‘html2.html’),和app裏存放的模板調用的時候同名,
同名的狀況下,集中存放的優先級高,匹配到集中存放的,就不會再去app中的模板文件夾去找了,
因此集中存放要給每一個app再加一層文件夾,區分一下相對路徑和名字,避免想調用app裏模板文件調用不到的狀況
二.模板變量
1)首先要明白什麼是靜態頁面什麼是動態頁面
(1)靜態頁面,即靜態網頁,是實際存在的,無需通過服務器的編譯,直接加載到客戶瀏覽器上顯示出來,只加載一次。靜態頁面須要佔必定的服務器空間,且不能自主管理髮布更新的頁面,
若是想更新網頁內容,要經過FTP軟件把文件DOWN下來用網頁製做軟件修改(經過fso等技術例外)。常見的靜態頁面舉例:.html擴展名的、.htm擴展名的。
靜態網頁每一個網頁都有一個固定的URL
(2)動態頁面,只要是採用了動態網站技術生成的網頁均可以稱爲動態網頁。頁面代碼雖然沒有變,可是顯示的內容倒是能夠隨着時間、環境或者數據庫操做的結果而發生改變的。
動態網頁是基本的html語法規範與Java、VB、VC等高級程序設計語言、數據庫編程等多種技術的融合,以期實現對網站內容和風格的高效、動態和交互式的管理。
所以,從這個意義上來說,凡是結合了HTML之外的高級程序設計語言和數據庫技術進行的網頁編程技術生成的網頁都是動態網頁。
以.aspx、.asp、.jsp、.php、.perl、.cgi等形式爲後綴,而且在動態網頁網址中有一個標誌性的符號——「?」。
(3)靜態:優勢,速度快,能夠跨平臺,跨服務器,安全。
缺點,更新困難,沒法實現一些WEB應用。最明顯的一點搜索。
動態:優勢,可用於在服務器上生成功能強大的 Web應用程序,加強的性能,世界級的工具支持,威力和靈活性。
缺點,速度不佔優點,在搜索引擎收錄方面不佔優點,動態網頁是在用戶輸入指令後才造成的頁面,並不存在這個頁面,而搜索引擎只會抓取現成的,並不會本身輸入
2)渲染 render方法會動態的生成最終的返回結果,例如在頁面上顯示當前服務器時間,能夠定義一個變量,按照必定的語法把變量的值渲染到模板中,本質:在最底層是字符串格式化
(1)須要加動態效果的視圖函數中定義變量,在返回的render方法中,模板參數後加個context參數,他是個字典,鍵是本身起名,值是上面定義的變量
(2)在對應的模板文件中,使用這個變量,要用雙層的花括號擴起來{{變量名}},注意模板裏的變量名必須和視圖函數中return出去的context裏面的key對應,而不是和視圖函數中定義的變量名對應
(3)視圖函數中返回的render方法會幫咱們把這個變量值替換到模板中的這個指定位置
若是變量是時間,不一樣時間訪問它,頁面顯示就不一樣,課堂上簡單例子是UTC時間,python
*想設置不是UTC時間,能夠更改項目文件夾settings.py中的TIME_ZONE的值,改成你想顯示的時區的時區簡寫,好比'Asia/Shanghai'
*views.py中 ,首先導入from datetime import datetime 在想編輯的視圖函數中now = datetime.now()返回return render(request,'app1/html1.html', context={'now': now},)
模板中 {{now}}就能把視圖函數中的context參數dict裏'now'這個key的值渲染到模板中寫了 {{now}}的位置數據庫
def index(request): now = datetime.now()#拿到當前時間,把他傳給模板
return render(request, 'app1/html1.html', context={ 'now': now, )
<h2>當前時間是:{{now}}</h2>
想設置不是UTC時間,能夠更改項目文件夾settings.py中的TIME_ZONE的值,改成你想顯示的時區的時區簡寫,好比'Asia/Shanghai'django
# Internationalization # https://docs.djangoproject.com/en/2.1/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = True
3)模板變量
命名:和python中變量命名規則差很少,由字母、數字、下劃線組成, 不能如下劃線開頭,不能有空格和下劃線之外的標點符號,不能用python和django的關鍵字命名
變量的值:能夠是python中的任意數據類型,包括函數,方法,屬性,對象實例等等,是對象實例的時候,頁面上解析出的是他的print值渲染上去的
4)變量的解析規則
1***舉例一:(1)渲染列表:1.視圖函數中定義變量,列表類型好比lt = [1,2,3],return中加上context={'lt':lt}
2.模板文件中<p>我是個列表:{{lt}}</p>
3.結果,顯示整個列表
(2)渲染列表中某個值:
1.視圖函數中仍是用原來的參數
2.模板的變量名後加.索引值(索引值對應列表,取第二個值,索引是1,以此類推,模板文件中<p>我是列表中第二個值:{{lt.1}}</p>
(3)渲染函數:1.視圖函數中定義函數,在視圖函數自己的return中的context參數中加上key:裏層函數名,裏層函數名不要帶上括號
2.模板中加上{{key}},這裏的key和上面那些同樣,仍是和以前同樣,是視圖函數中的對應參數的key,注意key仍是不要加()
3.若是裏層函數有返回值,則頁面中指定位置顯示裏層函數返回值,沒有返回值,則網頁對應位置顯示None
(4)渲染字典: 1.視圖函數中定義字典,返回的context參數中加上key:字典名
2.模板中加上{{key}}
3.結果是頁面中顯示整個字典
(5)渲染字典中某鍵的值 1.視圖函數仍是用上面的參數
2.模板中{{key.字典裏想取的值的key}}
3.結果顯示字典裏的對應值
(6)渲染對象的某個方法:1.視圖函數裏仍是用上面的字典不變
2.模板中{{key.該變量的方法}} ,好比<p>我調用字典的方法items:{{dc.items}}</p>
3.顯示該變量使用某方法後的返回值:
dict_items([('day4', '魔王拋棄了大白兔,選擇留下勇者啦'), ('day1', '大白兔被魔王抓走啦'), ('day2', '大白兔被魔王那啥啦'), ('day3', '勇者來救大白兔啦')])
4.視圖函數中定義的變量,若是該變量的對象自己有叫作那個方法的鍵:好比dt = {'name':"心藍",‘age':18,'items':'adc'},而後把'dt':dt放進context參數中return出去
5.模板中{{key.該變量被定義了同名的鍵的方法},具體例子是{{dt.items}}
6.結果顯示字典中寫好的值,而不是該對象的方法值(由於變量解析先進行字典鍵值查找,再進行方法屬性查找)編程
def index(request): now = datetime.now()#拿到當前時間,把他傳給模板 lt = [1, 2, 3] def func(): t = 1+1 # return '我是一個函數,你是誰鴨' dc = {"day1": "大白兔被魔王抓走啦", 'day2': "大白兔被魔王那啥啦", "day3": "勇者來救大白兔啦", "day4": "魔王拋棄了大白兔,選擇留下勇者啦" } dt = {'name': "心藍", 'age': 18, 'items': 'adc' } return render(request, 'app1/html1.html', context={ 'now': now, 'lt': lt, 'funccc': func, 'dc': dc, 'dt': dt, })#加一個context參數,他是個dict,帶上這個參數,在模板裏可使用他
<body> <h1>我是app1中的主頁面</h1> <h2>當前時間是:{{now}}</h2> <p>我是個列表:{{lt}}</p> <p>我是列表中第二個值:{{lt.1}}</p> <p>我是個函數:{{funccc}}</p> <p>我是個字典:{{dc}}</p> <p>我是字典裏的一個值:{{dc.day2}}</p> <p>我調用字典的方法items:{{dc.items}}</p> <p>我調用字典的方法items:{{dt.items}}</p> <form action=""> <p>用戶名: <input type="text"></p> <p>密碼: <input type="password"></p> <p><input type="submit" value="登錄"></p> </form> </body>
2.***具體的解析規則
1).計算變量,將其替換爲結果(變量是個表達式的話,頁面上會顯示錶達式計算後的結果)
2).遇到點(.)的時候,按一下順序查找:
-1.字典鍵值查找
-2.屬性或方法查找
-3.數字索引查找
3.***若是結果是可調用的,則調用它時不帶參數,調用的結果成爲模板的值。見上面的示例3
若是給裏層函數傳進去參數,則渲染失敗
好比示例3中的視圖函數定義時給裏層函數加上參數(aaa),這個函數就不會被渲染了
## 所謂的結果是可調用的,說明變量是個函數,或是個方法跨域
4.** 渲染失敗返回'',空字符串瀏覽器
***注意三種函數在頁面上顯示的不一樣,有返回值沒參數,沒返回值沒參數,有返回值有參數
***頁面上顯示結果:(1)我是個沒有返回值沒參數的函數:None
(2)我是個有返回值沒參數的函數:我是一個函數,你是誰鴨
(3)我是個有返回值有參數的函數: ----這裏是個空字符串
安全
def func(): t = 1+1 # return '我是一個函數,你是誰鴨' def func1(): t = 1+1 return '我是一個函數,你是誰鴨' def func2(a): t = 1 + 1 return '我是一個函數,你是誰鴨' return render(request, 'app1/html1.html', context={ 'now': now, 'lt': lt, 'funccc': func, 'funcc': func1, 'funcccc': func2, 'dc': dc, 'dt': dt, })
<p>我是個沒有返回值沒參數的函數:{{funccc}}</p> <p>我是個有返回值沒參數的函數:{{funcc}}</p> <p>我是個有返回值有參數的函數:{{funcccc}}</p>
三.模板過濾器 filter
1.引入模板過濾器概念:改變頁面顯示日期的格式
(1)第一種方法,不推薦:視圖函數中now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
頁面上顯示2019-02-24 10:21:53這樣格式的時間
(2)第二種方法,推薦:直接在模板上對變量進行處理,即便用過濾器(也叫篩選器):1.視圖函數不須要strftime,仍是now = datetime.now()
2.模板中{{now|date:'Y-m-d H-M-S'}}
3.結果顯示2019-02-24 10-Feb-th
(3)這裏面的date就是模板過濾器
2.經常使用模板過濾器
(1)add 將參數與值相加 首先嚐試轉換成整數相加,失敗,則嘗試全部可能,字符串,列表等。{{ value|add:"2" }}
參數若是是字符串也能夠,直接數字也能夠{{ value|add:2 }},若是參數是浮點數,會轉換成int處理{{ value|add:2.5 }}會轉換成{{ value|add:2 }}
參數沒法一步直接轉成int則頁面顯示空字符串好比{{ value|add:'2.5'}},
頁面上顯示結果爲value add 參數,規律:int add str ,頁面顯示空字符串,
int add int 頁面顯示倆int相加 ,
str add int,頁面顯示str後拼接str形式的數字,
str1 add str2,頁面顯示str1str2
1.值是整數,參數是整數,直接把參數和值相加
2.值是整數,參數是字符串,頁面顯示空字符串
3.值是字符串,參數是整數,把參數當成字符串,拼接到值後
4.值是字符串,參數是字符串,把參數當成字符串,拼接到值後
5.值是列表,參數是整數,頁面顯示‘’ --空字符串
6.值是列表,參數是字符串,頁面顯示‘’ --空字符串
7.值是字典,參數是整數,頁面顯示‘’ --空字符串
8.值是字典,參數是字符串,頁面顯示‘’ --空字符串
9.值是函數,參數是整數頁面顯示結果:根據函數的返回值add,若是函數返回值是整數則相加,字符串則拼接;函數解析失敗,或自己返回值爲空字符串則頁面上顯示add後的參數,
函數自己無返回值,頁面上顯示空字符串
10.值是函數,參數是字符串,頁面顯示結果。根據函數的返回值add,若是函數返回值是整數則顯示空字符串,字符串則拼接;函數解析失敗,或自己返回值爲空字符串則頁面上顯示add後的參數,
函數自己無返回值,頁面上顯示空字符串
****例如視圖函數中這樣設置
def func(): t = 1+1 # return '我是一個函數,你是誰鴨' def func1(): t = 1+1 return '我是一個函數,你是誰鴨' def func2(a): t = 1 + 1 return '我是一個函數,你是誰鴨' def func3(): return 1+1 def func4(): return '' dt = {'name': "毛毛蟲", 'age': 18, 'items': 'adc' } js = '<script>alert(1)</script>' html = '<h1>我是安全的<h1>' d3 = { 'int1': 1, 'str1': "abcde", 'str2': "abcde higk 233 六六六 lmn opq", 'list1': ['a', 's', 'd', 'w'], 'd1': {"hello": "world", 'howoldareyou': '怎麼總是你'}, 'f1': func1, #字符串返回值 'f2': func, #無返回值 'f3': func3, #整數返回值 'f4': func4 #返回空字符串 } return render(request, 'app1/html1.html', context={ 'now': now, 'lt': lt, 'funccc': func, 'funcc': func1, 'funcccc': func2, 'dc': dc, 'dt': dt, 'd3': d3, 'float1': 34.2324, 'js': js, 'html':html })
模板中
<h1>我是app1中的主頁面</h1> <h2>當前日期是:{{now|date:'Y-m-d H-M-S g-i-s'}}</h2> <h2>當前時間是:{{now|time:'H-i-s'}}</h2> <p>我是個列表:{{lt}}</p> <p>我是列表中第二個值:{{lt.1}}</p> <p>我是列表中第二個值加2:{{lt.1|add:'2'}}</p> <p>我是個沒有返回值沒參數的函數:{{funccc}}</p> <p>我是個有返回值沒參數的函數:{{funcc}}</p> <p>我是個有返回值有參數的函數:{{funcccc}}</p> <p>我是個字典:{{dc}}</p> <p>我是字典裏的一個值:{{dc.day2}}</p> <p>我調用字典的方法items:{{dc.items}}</p> <p>我調用字典的方法items:{{dt.items}}</p> <hr> <p>我試驗模板過濾器add整數,值是整數:{{d3.int1|add:"2"}}</p> <p>我試驗模板過濾器add字符串,值是整數:{{d3.int1|add:"-strrr"}}</p> <p>我試驗模板過濾器add整數,值是字符串:{{d3.str1|add:"2"}}</p> <p>我試驗模板過濾器add字符串,值是字符串:{{d3.str1|add:"-strrr"}}</p> <p>我試驗模板過濾器add整數,值是列表:{{d3.list1|add:"2"}}</p> <p>我試驗模板過濾器add字符串,值是列表:{{d3.list1|add:"-strrr"}}</p> <p>我試驗模板過濾器add整數,值是字典:{{d3.d1|add:"2"}}</p> <p>我試驗模板過濾器add字符串,值是字典:{{d3.d1|add:"-strrr"}}</p> <p>我試驗模板過濾器add整數,值是有字符串返回值的函數:{{d3.f1|add:"2"}}</p> <p>我試驗模板過濾器add整數,值是無返回值的函數:{{d3.f2|add:"2"}}</p> <p>我試驗模板過濾器add整數,值是有整數返回值的函數:{{d3.f3|add:"2"}}</p> <p>我試驗模板過濾器add整數,值是解析失敗的函數:{{funcccc|add:'2'}}</p> <p>我試驗模板過濾器add整數,值是返回值爲空字符串的函數:{{d3.f4|add:'2'}}</p> <p>我試驗模板過濾器add字符串,值是有字符串返回值的函數:{{d3.f1|add:"-strrr"}}</p> <p>我試驗模板過濾器add字符串,值是無返回值的函數:{{d3.f2|add:"-strrr"}}</p> <p>我試驗模板過濾器add字符串,值是有整數返回值的函數:{{d3.f3|add:"-strrr"}}</p> <p>我試驗模板過濾器add字符串,值是解析失敗的函數:{{funcccc|add:'-strrr'}}</p> <p>我試驗模板過濾器add字符串,值是返回值爲空字符串的函數:{{d3.f4|add:'-strrr'}}</p> <hr>
結果
(2)cut 移除值中全部指定的字符串。相似於 python 中的 replace(args,"") 。
好比模板中:<p>我試驗模板過濾器cut字符串,值是字符串:{{d3.str1|cut:"cd"}}</p>
結果:我試驗模板過濾器cut字符串,值是字符串:abe
(3)capfirst 首字母大寫,若是第一個字母不是字母則不起做用。{{ value|capfirst }},一整個字符串只有第一個單詞的首字母大寫
模板中:<p>我試驗模板過濾器capfrist,值是字符串str2:{{d3.str2|capfirst}}</p>
結果:我試驗模板過濾器capfrist,值是字符串str2:Abcde higk 233 六六六 lmn opq
(4)date 日期格式化 {{ value|date:"D d M Y" }} date過濾器裏包含了time,因此date過濾器裏也能夠用下面time的那些參數
具體字母含義Y:四位數的年。如1999
y:兩位數的年。如99
m:兩位數的月。如01,09
n:一位數的月。如1,9,12
d:兩位數的日。如01,09,31
j:一位數的日。如1,9,31
(5)time 時間格式化 {{ value|time:"H:i" }} 格式化格式見官方文檔:https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#date,
可是time不能包含時間,不能加參數年月日等
具體字母含義:g:12小時制的一位數的小時。如1,9,12
G:24小時制的一位數的小時。如0,8,23
h : 12小時制的兩位數的小時。如01,09,12
H:24小時制的兩位數的小時。如01,13,23
i:分鐘,從00到59
s:秒,從00到59
<h2>當前日期是:{{now|date:'Y-m-d H-M-S g-i-s'}}</h2> <h2>當前時間是:{{now|time:'H-i-s'}}</h2> <p>我是讓大家看看str1本來的樣子:{{d3.str1}}</p> <p>我試驗模板過濾器cut字符串,值是字符串str1:{{d3.str1|cut:"cd"}}</p> <p>我試驗模板過濾器capfrist,值是字符串str2:{{d3.str2|capfirst}}</p> <hr>
(6)default 若是變量解析失敗,使用給定的默認值。{{ value|default:"nothing" }}(注意若是value是''空字符串或None,輸出將會是'nothing')
模板中<p>我試驗模板過濾器default,值是解析失敗的函數:{{funcccc|default:"函數解析不成功,我是湊數的"}}</p>
<p>我試驗模板過濾器default,值是無返回值的函數:{{d3.f2|default:"函數無返回值,我是湊數的"}}</p>
<p>我試驗模板過濾器default,值是返回空字符串的函數:{{d3.f4|default:"函數返回空字符串,我是湊數的"}}</p>
結果:我試驗模板過濾器default,值是解析失敗的函數:函數解析不成功,我是湊數的
我試驗模板過濾器default,值是無返回值的函數:函數無返回值,我是湊數的
我試驗模板過濾器default,值是返回空字符串的函數:函數返回空字符串,我是湊數的
過濾器能夠用鏈式的方式,能夠過濾器後加過濾器,能夠在後面加無數個過濾器
模板中 <p>我試驗模板過濾器default鏈接模板過濾器add,值是解析失敗的函數:{{funcccc|default:"函數解析不成功,我是湊數的"|add:'-strrr'}}</p>
結果:我試驗模板過濾器default鏈接模板過濾器add,值是解析失敗的函數:函數解析不成功,我是湊數的-strrr
(7)first 返回列表的第一個元素 {{ value|first }}
模板中: {# <p>我是整數的第一個元素:{{d3.int1|first}}</p>#} ------值爲整數用first過濾器頁面會報錯
<p>我是列表的第一個元素:{{lt|first}}</p>
<p>我是字符串的第一個元素:{{d3.str1|first}}</p>
{# <p>我是字典的第一個元素:{{d3.d1|first}}</p>#}
<p>我是有字符串返回值的函數的第一個元素:{{d3.f1|first}}</p>
{# <p>我是有整數返回值的函數的第一個元素:{{d3.f3|first}}</p>#} ----整數返回值的函數用first過濾器頁面會報錯
<p>我是註定解析失敗的函數的第一個元素:{{funcccc|first}}</p>
{# <p>我是無返回值的函數的第一個元素:{{d3.f2|first}}</p>#} -----無返回值的函數用first過濾器頁面會報錯
<p>我是返回值爲空字符串的函數的第一個元素:{{d3.f4|first}}</p>
結果:我是整數的第一個元素:
我是列表的第一個元素:1
我是字符串的第一個元素:a
我是有字符串返回值的函數的第一個元素:我
我是註定解析失敗的函數的第一個元素:
我是返回值爲空字符串的函數的第一個元素:
(8)last 返回列表的最有一個元素 {{ value|last }}
和first用法大體相同,結果是返回值中的最後一個元素
(9)slice 返回一個列表的切片 {{ some_list|slice:":2" }}
模板中:<p>我是列表的倒序:{{lt|slice:'::-1'}}</p>
<p>我是字符串的倒序:{{d3.str1|slice:'::-1'}}</p>
結果:我是列表的倒序:[3, 2, 1]
我是字符串的倒序:edcba
(10)join 鏈接字符串列表 與str.join(list)同樣 {{ value|join:" // " }}
模板中:<p>我是列表元素的拼接:{{lt|join:'.'}}</p>
結果:我是列表元素的拼接:1.2.3
<p>我試驗模板過濾器default,值是解析失敗的函數:{{funcccc|default:"函數解析不成功,我是湊數的"}}</p> <p>我試驗模板過濾器default,值是無返回值的函數:{{d3.f2|default:"函數無返回值,我是湊數的"}}</p> <p>我試驗模板過濾器default,值是返回空字符串的函數:{{d3.f4|default:"函數返回空字符串,我是湊數的"}}</p> <p>我試驗模板過濾器default鏈接模板過濾器add,值是解析失敗的函數:{{funcccc|default:"函數解析不成功,我是湊數的"|add:'-strrr'}}</p> <hr> {# 註釋的行爲試驗過頁面會報錯的值的類型 #} {# <p>我是整數的第一個元素:{{d3.int1|first}}</p>#} <p>我是列表的第一個元素:{{lt|first}}</p> <p>我是字符串的第一個元素:{{d3.str1|first}}</p> {# <p>我是字典的第一個元素:{{d3.d1|first}}</p>#} <p>我是有字符串返回值的函數的第一個元素:{{d3.f1|first}}</p> {# <p>我是有整數返回值的函數的第一個元素:{{d3.f3|first}}</p>#} <p>我是註定解析失敗的函數的第一個元素:{{funcccc|first}}</p> {# <p>我是無返回值的函數的第一個元素:{{d3.f2|first}}</p>#} <p>我是返回值爲空字符串的函數的第一個元素:{{d3.f4|first}}</p> <p>我是列表的最後一個元素:{{lt|last}}</p> <p>我是字符串的最後一個元素:{{d3.str1|last}}</p> <p>我是有字符串返回值的函數的最後一個元素:{{d3.f1|last}}</p> {# <p>我是有整數返回值的函數的最後一個元素:{{d3.f3|last}}</p>#} <p>我是註定解析失敗的函數的最後一個元素:{{funcccc|last}}</p> {# <p>我是無返回值的函數的最後一個元素:{{d3.f2|last}}</p>#} <p>我是返回值爲空字符串的函數的最後一個元素:{{d3.f4|last}}</p> <hr> <p>我是列表的倒序:{{lt|slice:'::-1'}}</p> <p>我是字符串的倒序:{{d3.str1|slice:'::-1'}}</p> <hr> <p>我是列表元素的拼接:{{lt|join:'.'}}</p>
(11)floatformat 浮點數格式化 不指定小數位參數,默認保留一個爲小數
value Template Output
34.23234 {{ value|floatformat }} 34.2
34.23234 {{ value|floatformat:3 }} 34.232
視圖函數中:返回的參數加一個鍵值對'float1':34.2324
模板中:<p>我是浮點數格式化輸出默認格式(默認小數點後一位):{{float1|floatformat}}</p>
<p>我是浮點數格式化輸出保留小數點後指定位數:{{float1|floatformat:3}}</p>
結果:我是浮點數格式化輸出默認格式(默認小數點後一位):34.2
我是浮點數格式化輸出保留小數點後指定位數:34.232
(15)length 返回字符串或列表的長度
(16)length_is 判斷字符串或列表長度是否指定的值,相等返回True {{ value|length_is:"4" }}
模板中: <p>列表{{lt}}的長度是{{lt|length}}嗎:{{lt|length_is:'3'}}</p> ----{{lt|length_is:3}}length_is 的參數是整數類型仍是能一次轉換成整數格式的字符串均可以
結果:列表[1, 2, 3]的長度是3嗎:True
(17)lower 字符串中的字母都變小寫{{ value|lower }}
(18)upper 字符串中的字母都變大寫{{ value|upper }}
(19)safe 關閉變量的自動轉義,使html標籤生效{{ value|safe }} 爲了安全,django模板引擎默認幫咱們自動轉義html標籤,不執行js代碼,
須要腳本功能時,能夠給js變量加safe過濾器,關閉自動轉義功能,纔會執行js代碼
視圖函數中:加一個變量html= '<h1>我是安全的<h1>',把他在return的context加一個新鍵值對‘html’:html
模板中:不加safe過濾器:<p>{{html}}<p>
加safe過濾器:<p>{{html|safe}}<p>
結果:<h1>我是安全的<h1>
我是安全的 ---頁面上h1標題樣式的樣子,加粗加大的
(20)title 標題化,首字母大寫 {{ value|title }} 一個字符串中的每一個單詞的首字母都大寫,字母和字母隔開系統就認爲是個單詞,不是字母的不大寫
模板中:<p>我試驗模板過濾器title,值是字符串str2:{{d3.str2|title}}</p>
結果:我試驗模板過濾器capfrist,值是字符串str2:Abcde Higk 233 六六六 Lmn Opq
<p>我是浮點數格式化輸出默認格式(默認小數點後一位):{{float1|floatformat}}</p> <p>我是浮點數格式化輸出保留小數點後指定位數:{{float1|floatformat:3}}</p> <p>列表{{lt}}的長度是{{lt|length}}嗎:{{lt|length_is:'3'}}</p> <p>{{html}}<p> <p>{{html|safe}}<p> <p>我試驗模板過濾器title,值是字符串str2:{{d3.str2|title}}</p>
3.xss(跨域腳本攻擊 Cross Site Scripting)
1)反射型:非持久化,須要欺騙用戶本身去點擊連接才能觸發XSS代碼(服務器中沒有這樣的頁面和內容),通常容易出如今搜索頁面。
2)存儲型:持久化,代碼是存儲在服務器中的,如在我的信息或發表文章等地方,加入代碼,若是沒有過濾或過濾不嚴,那麼這些代碼將儲存到服務器中,用戶訪問該頁面的時候觸發代碼執行。
這種XSS比較危險,容易形成蠕蟲,盜竊cookie(雖然還有種DOM型XSS,可是也仍是包括在存儲型XSS內)。
客戶端的不安全性輸入引發的攻擊,例如,寫博客的時候,寫什麼顯示什麼,若是寫一個js函數放在上面,其餘客戶端點擊進去執行這個js函數,就可能受到攻擊,瀏覽器的cookies被竊取等,還有危害更大的存到數據庫等等
好比:視圖函數中:加一個變量js = '<script>alert("1")</script>',把他在return的context加一個新鍵值對‘js’:js
模板中:任意處加{{js}}
結果:<script>alert("1")</script>
若是模板中加safe模板過濾器,則頁面會出個彈窗顯示1
django模板引擎自動把xss給去掉了,自動轉義html標籤,把帶尖括號的html標籤轉義成純文本,不執行js代碼
js = '<script>alert(1)</script>' return render(request, 'app1/html1.html', context={ 'now': now, 'lt': lt, 'funccc': func, 'funcc': func1, 'funcccc': func2, 'dc': dc, 'dt': dt, 'd3': d3, 'float1': 34.2324, 'js': js, 'html':html })
{{js}}
{{js|safe}}
四.靜態文件
-css
-js
-圖片
查找和對模板文件查找相似
-1. 路徑配置
1)原理:django項目運行時首先在每一個app下面找有沒有STATIC子目錄,咱們能夠設置統一管理靜態文件而不是在app中分散存放
2)具體設置:
1項目根目錄中新建static文件夾
2 在項目文件裏的settings.py中找STATICFILES_DIRS 沒有就本身加上
STATICFILES_DIRS = [os.path.join(BASE_DIR,static)]
STATIC_URL =‘/static/’靜態文件的前綴,‘/static/’是默認值,和咱們本身建立的文件夾static沒有關係,能夠寫成任意值,暫時不須要動,可是必須有,先後都要帶/
3 在static文件夾中爲app建立同名的文件夾
3 STATIC_URL
-2. 靜態文件的引入
舉例在指定的app下css中新建一個stylesheet,叫作index.css,編寫樣式
p{
color: crimson;
}
想要在某模板上引用這個css,有兩種方式:
-1. 硬編碼 經過 STATIC_URL,不推薦
在想引用樣式表的模板中,head標籤裏 加上<link rel='stylesheet' href='/static/app1/css/index.css'> 這裏最前面的/static/就是上面settings.py中STATIC_URL的值,和STATICFILES_DIRS裏的文件夾無關
<link rel="stylesheet" href="/static/app1/css/index.css">
-2. 模板標籤 這樣是動態的解析
1)首先在整個模板的最上面加上{% load static %}
2)在head標籤中加<link rel='stylesheet' href="{% static '相對路徑' %}"> 這個相對路徑是從app名開始算起
好比本項目裏給app1的index頁面加,就是<link rel='stylesheet' href=「{% static 'app1/css/index.css' %}">
此種方式下,瀏覽器中查看,若是f12,頁面中head裏的link 中的href = '/static/app1/css/index.css'最前面的/static/會隨着settings裏的STATIC_URL設置動態變化
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>app1_index</title> <link rel='stylesheet' href="{% static 'app1/css/index.css'%}">
兩種方式最後結果都是