鼠年全馬鐵人挑戰 - WEEK 02
前言 Django提供獨特的模板語法,將HTML頁面做動態載入。因為在HTML檔,無法使用python來撰寫程式,Django的模板引擎讓撰寫好的python程式碼可以建構在網頁上面。簡單來說,透過模板語法,我們可以在HTML檔寫入python的程式碼,讓網頁變成動態載入的狀態。
Template相關設定(Configuration) 至專案根目錄下找到settings.py
檔案,搜尋TEMPLATES
,便能夠看到以下設定:
Django 預設去找 TEMPLATES
的設定DIRS
: 為Django額外搜尋TEMPLATES
的目錄,如果要另外設定的話,在這個地方填寫自訂的路徑
一般情況下,會習慣在每個新增apps 專案目錄下創建該apps 的專屬templates
資料夾,因為Django預設會去找名為templates 資料夾下的檔案。
實作 註冊APP 先建立Django application(app),例如建立名為food的app,並在settings.py
檔案下找到INSTALLED_APPS
,在末端加入'food'
。
指定專案路徑 再到urls.py
,設定path('food/', include("food.urls") ),
,指定food專案的根路徑。
建立模板 在food資料夾下另外設立一個template 目錄,新增index.html
(我有多一層food資料夾做區分)index.html
1 2 3 4 5 6 7 8 9 10 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Index</title > </head > <body > <h2 > Welcome to Django!!!</h2 > </body > </html >
載入模板並進行渲染(render
) app專案下的views.py
寫入下方程式碼
1 2 3 4 5 6 from django.shortcuts import renderfrom django.http import HttpResponsefrom django.template import loader def index (request ): template = loader.get_template('food/index.html' ) return HttpResponse(template.render())
查看頁面 開啟伺服器,執行python3 manage.py runserver
,原始網頁路徑加上/food
即可看到渲染出來的index.html
畫面
各式語法 變數(Variables) 兩個花括弧{ {} }
裡面放入傳遞過去的變數。
範例 傳遞Hello index!
訊息,並assign給變數名txt
,將此變數傳遞到index.html
檔進行渲染。views.py
1 2 3 4 from django.shortcuts import renderdef index (request ): txt = "Hello index!" return render(request, 'food/index.html' , {"txt" : txt} )
在index.html
檔中加入<h3> { {txt} } </h3>
,變數的值就會被模板語法渲染上去了!
1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Index</title > </head > <body > <h2 > Welcome to Django!!!</h2 > <h3 > { {txt} } </h3 > </body > </html >
Django提供填入標籤的模板語法: { % tag % }
,藉由{ % tag % }
可以寫入更複雜的邏輯,如:if-else
、for
等等。
條件判斷 1 2 3 4 5 6 7 { % 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 % }
迴圈 1 2 3 4 5 <ul> { % for athlete in athlete_list % } <li>{ { athlete.name } }</li> { % endfor % } </ul>
繼承 Django提供繼承的模板語法,讓開發者可以做到重複利用、彈性更動。
定義一個區間,讓繼承者做更動 => 彈性更動
1 { % block name % } .... { % endblock % }
很多時候一個網站某部分的頁面會重複,為了避免一直寫重複的代碼,可以使用extends tags 。 => 重複利用
1 { % extends "xxx.html" % }
實際應用時,通常會針對網頁重複的部分獨立出一個HTML檔。
實作 建立一個base.html
的HTML,網頁內容重複的部分都寫在這個檔,例如:網站的導覽條
base.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <!doctype html > <html lang ="en" > <head > <meta charset ="utf-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1, shrink-to-fit=no" > <link rel ="stylesheet" href ="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity ="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin ="anonymous" > <title > Index</title > </head > <body > <nav class ="navbar navbar-dark bg-dark" > <a href ="#" class ="navbar-brand" > FoodApp</a > <div class ="navbar" > <a href ="#" class ="nav-item nav-link" > Add Item</a > <a href ="#" class ="nav-item nav-link" > Delete Item</a > <a href ="#" class ="nav-item nav-link" > Menu Item</a > </div > </nav > { % block body % } { % comment % } 此處為彈性更動之處 { % endcomment % } { % endblock % } <script src ="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity ="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin ="anonymous" > </script > <script src ="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity ="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin ="anonymous" > </script > <script src ="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity ="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin ="anonymous" > </script > </body > </html >
{ % block body % }{ % endblock % }
內就是之後被引入其他檔案中,會變動的內容。 再來看index.html
檔
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 { % extends 'food/base.html' % }<!doctype html > <html lang ="en" > <head > <meta charset ="utf-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1, shrink-to-fit=no" > <link rel ="stylesheet" href ="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity ="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin ="anonymous" > <title > Index</title > </head > <body > { % block body % } { % for item in item_list % } <div class ="row" > <div class ="col-md-3 offset-md-2" > <img class ="card" height ="150px" src ="{ { item.item_iamge } }" > </div > <div class ="col-md-4" > <h3 > { { item.item_name } }</h3 > <h4 > { { item.item_desc } }</h4 > <h5 > ${ { item.item_price } }</h5 > </div > <div class ="col-md-2" > <a href ="{ % url 'food:detail' item.id% }" class ="btn btn-success" > Details</a > </div > </div > { % endfor % } { % endblock % } <script src ="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity ="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin ="anonymous" > </script > <script src ="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity ="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin ="anonymous" > </script > <script src ="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity ="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin ="anonymous" > </script > </body > </html >
上面index.html
檔案內的{ % extends 'food/base.html' % }
作為繼承base.html
的結構,並在{ % block body % }... { % endblock % }
內寫上要變動的內容
結果
跨站請求偽造的防護
參閱