[TOC] 模板語法 兩種書寫格式: 變數相關 {{ }} 邏輯相關 {% %} 模板傳值 給html頁面傳值的兩種方式 第一種方式 弊端就是:當要傳的變數名很多的時候,就很麻煩 第二種 locals() locals() 會將當前所在的名稱空間中所有的名字全部傳遞給html頁面 傳值 基本數據類型 ...
目錄
模板語法
兩種書寫格式:
- 變數相關 {{ }}
- 邏輯相關 {% %}
模板傳值
給html頁面傳值的兩種方式
第一種方式
def test(request):
n = 1
f = 1.21
s = 'hellow world'
lt = [11, 22, 33, 44, 55, 66]
tu = (111, 222, 333)
dic = {'username': 'neo', 'password': '123'}
se = {1, 3, 5, 7, 9}
bo = True
return render(request, 'test.html', 'n': n, 'dic': dic)
弊端就是:當要傳的變數名很多的時候,就很麻煩
第二種 locals()
locals() 會將當前所在的名稱空間中所有的名字全部傳遞給html頁面
傳值 基本數據類型
def test(request):
n = 1
f = 1.21
s = 'hellow world'
lt = [11, 22, 33, 44, 55, 66]
tu = (111, 222, 333)
dic = {'username': 'neo', 'password': '123'}
se = {1, 3, 5, 7, 9}
bo = True
return render(request, 'test.html', locals())
前端接收:
<p>{{ n }}</p>
<p>{{ f }}</p>
<p>{{ lt }}</p>
<p>{{ tu }}</p>
<p>{{ s }}</p>
<p>{{ se }}</p>
<p>{{ bo }}</p>
<p>{{ dic }}</p>
傳函數名
def test(request):
def func1():
pass
return render(request, 'test.html', locals())
前端
<p>傳函數名 {{ func1 }}</p>
顯示效果:傳函數名 None
註意:
給HTML頁面傳遞函數名的時候,模板語法會自動加括弧調用該函數,並且將函數的返回值顯示在瀏覽器頁面上。
但是模板語法不支持函數傳參,意味著給html頁面傳的函數只能是不需要傳參數調用的函數。
傳類名和對象
def func1():
pass
class MyClass(object):
def get_self(self):
return 'get_self'
@classmethod
def get_cls(cls):
return 'get_cls'
@staticmethod
def get_func():
return 'get_func'
obj = MyClass()
前端:
<p>傳類名:{{ MyClass }}</p>
<p>傳對象名: {{ obj }}</p>
<p>{{ obj.get_cls }}</p>
<p>{{ obj.get_self }}</p>
<p>{{ obj.get_func }}</p>
總結:只要是能夠加括弧調用的 傳遞到html頁面上都會自動加括弧調用
過濾器
語法結構
用|
來使用, 會自動將 |
左邊的數據當作過濾器的第一個參數傳入, :
右邊的當作第二個參數
<p>統計長度:{{ s|length }}</p>
常用的方法
- 統計長度:
<p>統計長度:{{ s|length }}</p>
, 如果無法統計長度會預設返回0 - 加法運算:
{{ n|add:666 }}
, 內部異常捕獲 支持數字相加 字元串拼接 都不符合返回空 - 切片操作:
{{ lt|slice:'0:5:2' }}
, 顧頭不顧尾 也支持步長 - 自動轉成文件大小格式:
{{ file_size|filesizeformat }}
- 截取文本內容:
s|truncatechars:5
(按字元計算)截取五個字元,三個點也算 - 截取文本內容:
{{ s1|truncatewords:5 }}
, (按照空格計算) 截取五個單詞 三個點不算 - 判斷是否有值:
{{ is_value|default:'is_value變數名指向的值為空' }}
, 有值展示值本身 沒值展示預設值 - 展示帶有標簽的文本:
{{ sss }}
- 預設情況下 是不會自動轉換成前端html標簽,防止惡意攻擊
前後端取消轉義
前端:<p>{{ sss|safe}}</p>
這樣就可以自動轉換成前端html標簽
後端:
from django.utils.safestring import mark_safe
def test(request):
sss2 = "<h2>h2標簽</h2>"
res = mark_safe(sss2)
return render(request, 'test.html', locals())
# 前端傳res就行了
也就意味著 html代碼可以不在html文件內寫,可以在後端寫完了傳給前端
標簽
邏輯相關的語法
for迴圈:
<p>標簽 邏輯相關</p>
{% for foo in lt %}
<p>{{ forloop }}</p>
<p>{{ foo }}</p>
{% endfor %}
forloop 內置的對象:
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 6, 'revcounter0': 5, 'first': True, 'last': False}
if判斷
{% if s %}
<p>s有值</p>
{% else %}
<p>s沒有值</p>
{% endif %}
for迴圈和if判斷聯合使用
{% for foo in lt %}
{% if forloop.first %}
<p>第一次</p>
{% elif forloop.last %}
<p>最後一次</p>
{% else %}
<p>{{ foo }}有點意思</p>
{% endif %}
{% endfor %}
{% empty %}
<p>當for迴圈的對象是空的時候會走 </p>
with起別名
後端有個大字典,傳到前端:
comp_dic = {'username':'123', 'hobby':['study', 'run', ['rap', {'age':20}]]}
前端: <p>{{ comp_dic.hobby.2.1.age }}</p>
註意:模板語法的取值 只有一種方式 統一採用句點符
<p>當你的數據是通過多個句點符獲取到的,後續又需要經常使用,可以給該數據起別名,但別名只能在with內部使用</p>
{% with comp_dic.hobby.2.1.age as age %}
<p>{{ age }}</p>
{% endwith %}
自定義過濾器和標簽
django支持用戶自定義過濾器和標簽
有三個步驟:
在應用名下新建一個名字必須叫做templatetags的文件夾
在該文件夾內,新建一個任意名稱的py文件
在該py文件中,必須先寫下麵兩句代碼
from django.template import Library register = Library()
之後就可以用register自定義過濾器和標簽了
自定義過濾器
和預設的過濾器一樣 最多只能接受兩個參數
from django.template import Library
register = Library()
# 自定義過濾器
@register.filter(name='neo')
def index(a, b):
return a + b # 兩個數的和
需要先在html頁面上 載入
{% load mytag %}
{{ 1|neo:2 }}
自定義的過濾器可以在邏輯語句中使用,而自定義的標簽不可以
{% load mytag %}
{% if 1|neo:2 %}
<p>有值</p>
{% else %}
<p>沒有值</p>
{% endif %}
自定義標簽
可以接收任意多個參數,參數與參數之間必須空格隔開
from django.template import Library
register = Library()
@register.simple_tag(name='mytag')
def mytag(a,b,c,d):
return '%s*%s*%s*%s' % (a,b,c,d) # 接收四個參數用*拼接
自定義inclusion_tag
是一個函數,能夠接收外界傳入的參數,然後傳遞給一個頁面,頁面上獲取數據,渲染完成之後,將渲染好的頁面放到調用inclusion_tag的地方。
mytag.py
from django.template import Library
register = Library()
@register.inclusion_tag('mytag.html', name='xxx')
def func(n):
lt = []
for i in range(n):
lt.append(f'第{i}項')
return locals() # 將lt直接傳遞給mytag頁面
template文件夾下mytag.html
<ul>
{% for foo in lt %}
<li>{{ foo }}</li>
{% endfor %}
</ul>
views.py返回的test.html頁面
{% load mytag %}
{% xxx 5 %}
註意: 當你需要使用一些頁面組件的時候 並且該頁面組件需要參數才能夠正常渲染 你可以考慮使用inclusion_tag
模板的繼承
繼承模板extends
在子頁面中在頁面最上方使用下麵的語法來繼承母板
{% extends 'home.html' %}
塊(block)
在父頁面上利用block劃定想要修改的區域,繼承後就可以通過名字找到對應的名字找到該區域,並修改
- 模板上的block區域越多,頁面的擴展性越強,推薦你一個模板頁面至少有三塊區域(css區域,html代碼區域,js區域)
- 通過這三個區域,就能夠實現每一個頁面都有自己獨立的css和js代碼
- 可以在子頁面上通過{{ block.super }}沿用父頁面的內容
導入(include)
將html頁面當做模塊的直接導入使用:{% include 'form.html'%}
{% block content %}
<p>我改成home1頁面內容</p>
{{block.super}}
{% include 'form.html' %}
{% endblock %}
{% block css %}
<style>
p {
color: green;
}
</style>
{% endblock %}
{% block js %}
<script>
alert('login')
</script>
{% endblock %}