Django模板技術–Django播客系統(四)
如果使用react實現前端頁面,其實Django就沒有必須使用模板,它其實就是一個純後臺服務程序,接收請求,響應數據,前端接口設計就可以是純粹的Restful風格。
模板的目的就是爲了可視化,將數據按照一定佈局格式輸出,而不是爲了數據處理,所以一般不會有複雜的處理邏輯。模板的引入實現了業務邏輯和顯示格式的分離。這樣,在開發中,就可以分工協作,頁面開發完成頁面佈局設計,後臺開發完成數據處理邏輯實現。
- Python的模板引擎默認使用Django template language(DTL)構建
模板配置
- 在
djweb/settings.py
中,設置模板項目的路徑
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #這句話取項目根目錄
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.abspath(os.path.join(BASE_DIR,'templates'))], #制定模板文件夾路徑
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
- DIRS:列表,定義模板文件的搜索路徑順序。os.path.join(BASE_DIR,‘templates’)即項目根目錄下templates目錄,請構建這個目錄。
- 項目根目錄中構建templates文件夾。模板文件目錄
- 項目根目錄中構建templates文件夾。模板文件目錄
- APP_DIRS:是否運行在每個已經安裝的應用中查找模板。應用自己目錄下游templates目錄,例如:
django/contrilb/admin/templates
。如果應用需要可分離、可重用,建議吧模板放到應用目錄下 - BASE_DIR是項目根目錄,
os.path.join(BASE_DIR,'templates')
就是在manage.py這一層建立一個目錄templates。這個路徑就是以後默認找模板的地方。
模板渲染
-
模板頁
- 新建html文件,在
/templates/index.html
目錄下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Django web 模板技術</title> </head> <body> 我是模板,數據是{{content}} </body> </html>
- 新建html文件,在
-
模板處理
- 加載模板:模板是一個文件,需要從磁盤讀取並加載。要將模板放置在指定的模板文件夾中
- 渲染:模板需要使用內容數據渲染
- 測試:修改
djweb/urls.py
文件中的index函數。
from django.template import loader def index(request:HttpRequest): """視圖函數:請求進來返回響應""" template = loader.get_template("index.html") #加載器模塊搜索模板並加載它 print(template.origin) #顯示模板路徑 context = {"content":"www.xdd.com"} #字典數據 return HttpResponse(template.render(context,request))
- 運行server
python manage.py runserver
- 訪問
http://127.0.0.1:8000/
界面如下:可以看到
-
render快捷渲染函數
- 上面2個步驟代碼編寫繁瑣,Django提供了對其的封裝————快捷函數render。
render(request,template_name,context=None)
返回HTTPResponse對象- template_name #模板名稱
- context 數據字典
- render_to_string() 是其核心方法,其實就是拿數據替換HTML中的指定位置後返回一個字符串
from django.shortcuts import render def index(request:HttpRequest): """視圖函數:請求進來返回響應""" return render(request,"index.html",{"content":"www.xdd.com"})
DTL語法(模板語法)
變量
- 語法:
{{ variable }}
- 變量名由字母、數字、下劃線、點號組成。
- 點號使用的時候,例如foo.bar,遵循以下順序:
-
字典查找,例如
foo["bar"]
,把foo當做字典,bar當做key -
屬性或方法的查找,例如
foo.bar
,把foo當做對象,bar當做屬性或方法 -
數字索引查找,例如
foo[1]
,把foo當做列表一樣,使用索引訪問 -
示例: 修改
djweb/urls.py
文件中的index函數from django.shortcuts import render import datetime def index(request:HttpRequest): """視圖函數:請求進來返回響應""" my_dict = { "a":100, "b":0, "c":list(range(10,20)), "d":'abc', "date":datetime.datetime.now() } context = {"content":"www.xdd.com","my_dict":my_dict} return render(request,"index.html",context)
- 如果變量未能找到,則缺省插入空字符串。
- 在模板中調用方法,不能加小括號,自然也不能傳遞參數。
{{my_dict.a}}
複合第一條,當做字典的key就可以訪問了{{my_dict.keys}}
正確寫法。符合第二條,當做my_dict對象的屬性和方法。- 錯誤寫法
{{my_dict.keys()}}
。
-
模板標籤
-
if/else
標籤-
基本語法如下:
{% if condition %} ... display {% endif %}
{% if condition %} ... display 1 {% elif condition2 %} ... display 2 {% else %} ... display 3 {% endif %}
-
條件也支持
and、or、not
-
注意,因爲這些標籤是斷開的,所以不能像Python一樣使用縮進就可以表示出來,必須有個結束標籤,例如endif、endfor。
-
-
for
標籤<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Django web 模板技術</title> </head> <body> 我是模板,數據是{{content}} <ul> {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} </ul> <ul> {% for person in person_list %} <li> {{ person.name }}</li> {% endfor %} </ul> </body> </html>
變量 說明 forloop.counter
當前循環從1開始的計數 forloop.counter0
當前循環從0開始的計數 forloop.revcounter
從循環的末尾開始倒計數1 forloop.revcounter0
從循環的末尾開始倒計數到0 forloop.first
第一次進入循環 forloop.last
最後一次進入循環 forloop.parentloop
循環嵌套時,內層當前循環的外層循環 - 給標籤增加一個reversed使得該列表被反向迭代:
{% for athlete in athlete_list reversed %} ... {% empty %} ... 如果被迭代的列表是空的或者不存在,執行empty {% endfor %}
- 可以嵌套使用{% for %}標籤:
{% for athlete in athlete_list %} <h1>{{ athlete.name }}</h1> <ul> <% for sport in athlete.sports_played %> <li>{{ sport }}</li> <% endfor %> </ul> {% endfor %}
-
ifequel/ifnotequal
標籤{% ifequal %}
標籤比較兩個值,當他們相等時,顯示在{% ifequal %}
和{% endifequal %}
之中所有的值。下面的例子比較兩個模板變量user和currentuser:
{% ifequal user currentuser %} <h1>Welcome!</h1> {% endifequal %}
- 和
{% if %}
類似,{% ifequal %}
支持可選的{% else %}
標籤:
{% ifequal section 'sitenews' %} <h1>Site News</h1> {% else %} <h1>No News Here</h1> {% endifequal %}
- 其他標籤
- csrf_token用於跨站請求僞造保護,防止跨站攻擊的。
{% csrf_token %}
- csrf_token用於跨站請求僞造保護,防止跨站攻擊的。
-
註釋標籤
- 單行註釋
{# #}
- 多行註釋
{% comment %}... {% endcomment %}
{# 這是一個註釋 #} {% comment %} 這是多行註釋 {% endcomment %}
- 單行註釋
-
過濾器
- 模板過濾器可以在遍歷被顯示前修改它。
- 語法
{{ 變量|過濾器}}
- 過濾器使用管道字符
|
,例如{{ name|lower}}
,{{ name }}
變量被過濾器lower處理後,文檔大寫轉換文本爲小寫。 - 過濾管道可以被套接,一個過濾器管道的輸出又可以作爲下一個管道的輸入。
- 例如
{{ my_list|first|upper }}
,將列表第一個元素並將其轉化爲大寫。
- 例如
- 過濾器傳參
- 有些過濾器可以傳遞參數,過濾器的參數跟隨冒號之後並且總是以雙引號包含。
- 例如:
{{bio|truncatewords:"30"}}
,截取顯示變量bio的前30個詞。{{ my_list|join:"," }}
,將my_list的所有元素使用,
逗號連接起來
- 過濾器使用管道字符
- 其他過濾器
過濾器 說明 舉例 cut
切掉字符串中的指定字符 {{ value|cut:"b"}}
lower
轉換爲小寫 upper
轉換爲大寫 truncatewords
指定的長度截取字符串 {{ bio | truncatewords:"30"}}
join
對序列拼接 {{ d.e|join:"//"}}
first
取序列第一個元素last
取序列最後元素 yesno
變量可以是True、False、None
yesno的參數給定逗號分隔的三個值,返回3個值中的一個。
True對應第一個
False對應第二個
None對應第三個
如果參數只有2個,None等效False處理{{value | yesno:"yeah,no,maybe"}}
add
加法,參數是負數就是減法 數字加 {{value | add:"100"}}
列表合併{{mylist|add:newlist}}
divisibleby
能否被整除 {{value | divisibleby:"3" }}
能被3整除返回Trueaddslashes
在反斜槓、單引號或者雙引號前面加上反斜槓 {{value | addslashes }}
length
返回變量的長度 {% if my_list | length >1 %}
default
變量等價False則使用缺省值 {{value | default:"nothing"}}
default_if_none
變量爲None使用缺省值 {{value|default_if_none:"nothing"}}
date
格式化date或者datetime對象 實例: {{my_dict.date|date:'Y n j'}}
Y 2000年
n 1-12月
j 1-31日
模板實例
-
奇偶行列表輸出
- 使用下面字典my_dict的c的列表,在模板網頁中列表ul輸出多行數據
- 要求奇偶行顏色不同
- 每行有行號(從1開始)
- 列表中所有數據都增大100
from django.http import HttpResponse,HttpRequest,JsonResponse from django.template import loader from django.shortcuts import render import datetime def index(request:HttpRequest): """視圖函數:請求進來返回響應""" my_dict = { "a":100, "b":0, "c":list(range(10,20)), "d":'abc', "date":datetime.datetime.now() } context = {"content":"www.xdd.com","my_dict":my_dict} return render(request,"index.html",context)
- 模板頁面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Django web 模板技術</title> </head> <body> 我是模板,數據是{{content}} <ul> {% for athlete in my_dict.items %} {% ifequal athlete.0 "c" %} {% for dt in athlete.1 %} <li>{{ forloop.parentloop.counter }} | {{ forloop.counter }} | {{ athlete.0 }} -- {{ dt|add:"100" }}</li> {% endfor %} {% else %} {% ifequal athlete.0 "date" %} <li>{{ forloop.counter }} | {{ athlete.0 }} -- {{ athlete.1|date:'Y-n-j' }}</li> {% else %} <li>{{ forloop.counter }} | {{ athlete.0 }} </li> {% endifequal %} {% endifequal %} {% endfor %} </ul> </body> </html>
- 使用下面字典my_dict的c的列表,在模板網頁中列表ul輸出多行數據
附加–Pycharm模板自定義
- 第一步:
- 第二步
- 第三步