Django 模板
Django 模板

模板傳值取值
後端傳值
- 鍵值對形式:
{『name』:value}- 精準傳值,用啥傳啥
- 函數:
locals()locals()將當前名稱空間中所有的變數名全部傳遞給頁面
HTML取值
- 變數相關:
{{變數名}} - 邏輯相關:
{% 表達式 %}
在取值的時候需要注意以下幾點
* 傳遞函數名會自動加括弧調用,並返回return後的值
* 傳遞類名會自動加括弧調用實例化成對象
* 傳遞實例化對象名也返回對象,傳遞 對象.方法 可以獲取該的返回值
* 傳遞類和函數不需要加括弧,自動加括弧調用,模板語法不支援額外的傳參(形參,實參)
* HTML頁面取值可以通過點`.`的方式取值,不論是索引還是鍵值等···
eg:<p>{{ d.hobby.3.username }}</p>
# 索引就是.下標,字典就是.鍵
<p>{{ my_int }}</p>
<p>{{ my_float }}</p>
<p>{{ my_list }}</p>
<p>{{ my_tuple }}</p>
<p>{{ my_dict }}</p>
<p>{{ my_set }}</p>
<p>{{ my_bool }}</p>
<p>{{ get_func }}</p>
<p>{{ MyClass }}</p>
<p>{{ obj.get_cls }}</p>
<p>{{ obj.get_self }}</p>
<p>{{ obj.get_static }}</p>
def func(request):
my_int = 123
my_float = 3.14
my_list = [1, 2, 3, 4]
my_tuple = (1, 2, 3, 4,)
my_dict = {'name': 'Hammer'}
my_set = {1, 2, 3, 4}
my_bool = True
def get_func():
print('from get_func')
return 'get_func'
class MyClass(object):
def get_self(self):
return '綁定給對象的方法'
@classmethod
def get_cls(cls):
return '綁定給類的方法'
@staticmethod
def get_static():
return '靜態方法'
obj = MyClass()
return render(request,'func.html',locals())

過濾器
模板語法:{{ 變數名 | 過濾器:可選參數 }}
模板過濾器可以在變數被顯示前修改它,過濾器使用管道字元,如下所示:
{{ name|lower }}
# 過濾器處理後轉小寫
管道符的作用:一個過濾器管道的輸出又可以作為下一個管道的輸入
default
在html文件中,default 為變數提供一個默認值,如果views傳的變數布爾值為false,則使用指定的默認值,如果為true,就使用views傳的變數值;
from django.shortcuts import render
def func(request):
id = 0
return render(request,'func.html',locals()) # {'id':id}
'''html'''
<p>{{ id|default:'views傳的變數布爾值為false用我吧!' }}</p>

length
- 返回對象的長度,適用於字元串和列表
- 字典返回的是鍵值對的數量,集合返回的是去重後的長度
字元串:{{ my_str|length }}
列表:{{ my_list|length }}
字典:{{ my_dict|length }}
集合:{{ my_set|length }}
def func(request):
my_str = 'HammerZe'
my_list = [1, 2, 3, 4]
my_dict = {'name': 'HammerZe', 'age': 18}
my_set = {1, 1, 2, 2, 3, 3, 4, 4}
return render(request, 'func.html', locals())

filesizeformat
以更易讀的方式顯示文件的大小(即'13 KB', '4.1 MB', '102 bytes'等)
字典返回的是鍵值對的數量,集合返回的是去重後的長度
def func(request):
file_data = 1024*1024
return render(request, 'func.html', locals())
文件大小:{{ file_data|filesizeformat }}

date
根據給定格式對一個日期變數進行格式化。
格式 Y-m-d H:i:s返回 年-月-日 小時:分鐘:秒 的格式時間
def func(request):
import datetime
ctime = datetime.datetime.now()
return render(request, 'func.html', locals())
時間:{{ ctime|date:'Y-m-d H:i:s' }}

truncatechars
如果字元串包含的字元總個數多於指定的字元數量,那麼會被截斷掉後面的部分
截斷的字元串將以 ... 結尾,...也算三個字元,比如部落格園首頁示例
def func(request):
trun_str = 'HammerZe真帥'
return render(request, 'func.html', locals())
字元串截取:{{ trun_str|truncatechars:9 }}

truncatewords
該過濾器和truncatechars類似,但是...不計入長度,空格為分隔符,一個單詞為一個單元字元
from django.shortcuts import render
def func(request):
trun_str = 'HammerZe Hans He'
return render(request, 'func.html', locals())
字元串截取:{{ trun_str|truncatewords:2 }}

safe
將字元串標記為安全,不需要轉義。
前端:要保證 views.py 傳過來的數據絕對安全,才能用 safe。
後端: 使用views.py 的 mark_safe 效果相同
Django 會自動對 views.py 傳到HTML文件中的標籤語法進行轉義,令其語義失效。加 safe 過濾器是告訴 Django 該數據是安全的,不必對其進行轉義,可以讓該數據語義生效(這裡涉及到xss攻擊自行查閱)
from django.shortcuts import render
def func(request):
unsafe_str = '<h1>不轉義,語義失效,攜帶標籤</h1>'
safe_str = '<h1>轉義,語義生效,我是一級標題</h1>'
# 後端取消轉義
from django.utils.safestring import mark_safe
safe_str1 = mark_safe('<h1>後端取消轉義</h1>')
return render(request, 'func.html', locals())
{{ unsafe_str }}
{{ safe_str|safe }}
{{ safe_str1 }}

add
整型做加法運算,字元串做拼接
from django.shortcuts import render
def func(request):
add_num = 100
join_str = 'Hammer'
return render(request, 'func.html', locals())
<p>加法運算:{{ add_num|add:100 }}</p>
<p>字元串拼接:{{ join_str|add:'Ze' }}</p>

標籤
注釋標籤
Django 注釋使用 {# #}
{# 這是一個注釋 #}
if/else 標籤
- 語法格式:
{% if condition %}
... display
{% endif %}
或者
{% if condition1 %}
... display 1
{% elif condition2 %}
... display 2
{% else %}
... display 3
{% endif %}
# 示例
{% if my_str %}
{{ my_str }}
{% endif %}
def func(request):
my_str = 'HammerZe'
return render(request, 'func.html', locals())
# 頁面返回:HammerZe
{% if %} 標籤接受 and , or 或者 not 關鍵字來對多個變數做判斷 ,或者對變數取反( not ),例如:
{% if a and b %}
a 和 b 變數都是可用的。
{% endif %}
for 標籤
每一次循環中,模板系統會渲染在 {% for %} 和 {% endfor %} 之間的所有內容;
模板語法for循環和python 的for循環類似,支援in
from django.shortcuts import render
def func(request):
l = [1,2,3,4]
return render(request, 'func.html', locals())
{% for foo in l %}
{{ foo }}
{% endfor %}

給標籤增加一個 reversed 使得該列表被反向迭代
{% for foo in l reversed %}
{{ foo }}
{% endfor %}

遍歷字典: 可以直接用字典 .items 方法,用變數的解包分別獲取鍵和值
from django.shortcuts import render
def func(request):
my_dict = {'name': 'HammerZe', 'age': 18, 'gender': 'male'}
return render(request, 'func.html', locals())
# 分別獲取k,v
{% for k in my_dict %}
{{ k }}
{#{{ v }}#}
{% endfor %}

# 獲取k,v
{% for k,v in my_dict.items %}
{{ k }}
{{ v }}
{% endfor %}

forloop內置對象
{% for k in my_dict %}
{{ forloop }}
{% endfor %}

在 {% for %} 標籤里可以通過 {{forloop}} 變數獲取循環序號。
- forloop.counter: 順序獲取循環序號,從 1 開始計算
- forloop.counter0: 順序獲取循環序號,從 0 開始計算
- forloop.revcounter: 倒序獲取循環序號,結尾序號為 1
- forloop.revcounter0: 倒序獲取循環序號,結尾序號為 0
- forloop.first(一般配合if標籤使用): 第一條數據返回 True,其他數據返回 False
- forloop.last(一般配合if標籤使用): 最後一條數據返回 True,其他數據返回 False
{% for i in views_list %}
{#<p>{{ forloop.counter }}</p>#} # 1 2 3 4 5
{#<p>{{ forloop.counter0 }}</p>#} # 0 1 2 3 4
{#<p>{{ forloop.revcounter }}</p>#} # 5 4 3 2 1
{#<p>{{ forloop.revcounter0 }}</p>#} # 4 3 2 1 0
<p>{{ forloop.first }}</p> # True False False False False
<p>{{ forloop.last }}</p> # False False False False True
{% endfor %}
from django.shortcuts import render
def func(request):
views_list = ["a", "b", "c", "d", "e"]
return render(request, 'func.html', locals())
{% empty %}
{% empty %} 從句:在循環為空的時候執行(即 in 後面的參數布爾值為 False )
{% for i in views_list %}}}
{{ i }}
{% empty %}
空列表當然執行~
{% endfor %}

include 標籤
{% include %} 標籤允許在模板中包含其它的模板的內容,類似後端導入模組
{% include 'func2.html'%}
# func2.html
<h1>哈哈哈</h1>

csrf_token
作用:跨站請求偽造保護。
在我們使用form表單的時候,經常報403許可權錯誤,這裡我們可以在HTML頁面使用
{% csrf_token %},表單提交數據才會成功,或者在settings.py將中間件注釋掉也可以;
解析:
首先,向伺服器發送請求,獲取登錄頁面,此時中間件 csrf 會自動生成一個隱藏input標籤,該標籤里的 value 屬性的值是一個隨機的字元串,用戶獲取到登錄頁面的同時也獲取到了這個隱藏的input標籤。
然後,等用戶需要用到form表單提交數據的時候,會攜帶這個 input 標籤一起提交給中間件 csrf,原因是 form 表單提交數據時,會包括所有的 input 標籤,中間件 csrf 接收到數據時,會判斷,這個隨機字元串是不是第一次它發給用戶的那個,如果是,則數據提交成功,如果不是,則返回403許可權錯誤。
自定義過濾器
1、在應用目錄下創建 templatetags 目錄名只能是 templatetags;
2、在 templatetags 目錄下創建任意 py 文件,如:my_tag.py。
3、my_tag.py 文件程式碼如下:
from django import template
register = template.Library() #register的名字是固定的,不可改變
4、利用裝飾器 @register.filter 自定義過濾器
注意:自定義過濾器也只能接收兩個參數,因為|本質就是前面的參數交給後面過濾器處理,過濾器最強多可自帶一個參數
'''my_tag.py'''
# 自定義過濾器
@register.filter(name='myfilter')
def index(x,y):
return x * y
'''views.py'''
from django.shortcuts import render
def func(request):
a=10
return render(request, 'func.html', locals())
{#載入過濾器#}
{% load my_tag %}
{#使用過濾器#}
{{ a|myfilter:10 }}

5、自定義標籤
@register.simple_tag(name='mytag')
def tag(x, y, z): # 自定義標籤可以接收n個參數
return x + y + z
{#載入過濾器#}
{% load my_tag %}
{% mytag 1 2 3 %}

自定義 inclusion_tag

類似將html頁面功能分塊返回了~
自定義inclusion_tag,my_tag.py
from django import template
register = template.Library() # register的名字是固定的,不可改變
@register.inclusion_tag('login.html',name='my_inclusion')
def inclusion(n):
l = []
for i in range(1,n):
l.append(f'第{i}頁')
return locals() # 將當前名稱空間所有名字返回給login.html
views.py
def func(request):
return render(request, 'func.html', locals())
lit.py 中間html
<ul>
{% for foo in l %}
<li>{{ foo}}</li>
{% endfor %}
</ul>
func.html
{#載入過濾器#}
{% load my_tag %}
{#生成10個li#}
{% my_inclusion 10 %}
模板繼承
模板可以用繼承的方式來實現復用,減少冗餘內容。
網頁的頭部和尾部內容一般都是一致的,我們就可以通過模板繼承來實現復用。
父模板用於放置可重複利用的內容,子模板繼承父模板的內容,並放置自己的內容。
父模板
標籤 block...endblock: 父模板中的預留區域,該區域留給子模板填充差異性的內容,不同預留區域名字不能相同
{% block 名稱 %}
預留給子模板的區域,可以設置設置默認內容
{% endblock 名稱 %}
子模板
子模板使用標籤 extends 繼承父模板:
{% extends "父模板路徑"%}
子模板如果沒有設置父模板預留區域的內容,則使用在父模板設置的默認內容,當然也可以都不設置,就為空。
子模板設置父模板預留區域的內容:
{% block 名稱 %}
子內容
{% endblock 名稱 %}
子版也可以繼續使用母版劃定區域內的內容
{{ block.super }}
父模板如何劃分區域
劃定區域的時候一般都應該有三個區域:CSS區域,HTML文檔區域、JS區域
這樣劃分區域提高了頁面的可擴展性和方便維護等優點
{% block css %}
{% endblock %}
{% block content %}
{% endblock %}
{% block js %}
{% endblock %}
