目錄html
使用 Django的 模板系統 (Template System)來實現將Python代碼和HTML代碼分開的目的。
python的模板包涵:HTML代碼+邏輯控制代碼
, 將具體數據嵌入到前端模板的語法,在一個html文件中包含模板語法的文件,能夠認爲是模板文件前端
主要分爲兩部分:渲染變量使用雙大括號{{ }}
,渲染標籤則使用雙大括號雙百分號{% %}
python
在html頁面中使用兩個大括號包起來的字符串叫作變量:shell
{{ Var_name }}
這裏經過python django的shell環境來舉例(在這個環境中能夠直接引用 所屬django模塊中的變量等信息)django
# 使用 manage.py進入shell界面 終端中輸入:python manage.py shell >>> from django.template import Context,Template >>> t = Template('My name is {{ name }}') >>> c = Context({'name':'dachenzi'}) >>> t.render(c) # render會把變量進行渲染 'My name is dachenzi' >>>
單行註釋 {# #}
。
多行註釋 {% comment %} ... {% endcomment %}
.後端
{# 這是一個註釋 #} {% comment %} 這是多行註釋 {% endcomment %}.
若是傳遞的變量是屬組或者字典,那麼須要進行深度查詢(經過使用.(點)來完成深度查詢):app
{{ Var_Name.username }} # 獲取Var_Name中的key爲:username的值 --> 變量爲字典類型 {{ Var_Name.2 }} # 獲取Var_Name中第2個值 --> 變量爲list類型
使用.帶進行深度查詢,查詢list類型的數據框架
>>> from django.template import context,Template >>> t = Template('hello {{ name.1}}') >>> c = Context({'name':[1,2,3]}) >>> t.render(c) 'hello 2'
使用items
循環字典類型(不加括號)函數
{% for key,value in user_dict.items %} <li>{{ key }}-{{ value }}</li> {% endfor %}
能夠理解爲python中的內置函數,過濾器是模板的特有語法,經過前端來過濾部分數據。注意filter只能傳遞一個參數(也能夠說是兩個參數,由於第一個個參數已經固定,就是被處理的那個)。
格式:oop
{{ var|method:parameter}}
method表示過濾器部分過濾器以下:
過濾器 | 說明 | 舉例 |
---|---|---|
first | 取列表第一個元素 | |
last | 取列表最後元素 | |
capfirst | 首字母大寫 | |
cut | 從字符串中移除指定的字符 | {{ 'aLbLcL'|cut:'L' }}答案是abc |
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整除返回True | |
addslashes | 在反斜槓、單引號或者雙引號前面加上反斜槓 {{ 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 日 |
切片相關 | {{ value7|filesizeformat }}文件的字節數 {{ value7|first }}第一個字符 {{ value7|length }}長度 {{ value7|slice:":-1" }}切片 |
內置的過濾器總有不能知足咱們業務需求的時候,這時,咱們能夠自定義過濾器,官方文檔:https://docs.djangoproject.com/zh-hans/2.0/howto/custom-template-tags/
具體步驟爲:
app目錄下
建立templatetags包(名稱必須爲templatetags
)下面是my_tags.py的文件內容
from django import template # 須要先導入文件 register = template.Library() # register的名字是固定的,不可改變,由於下面會進行調用 @register.filter # 註冊 def multi(num1,num2): return num1 * num2
在引用的html模板文件中進行加載(能夠放在模板文件頭部,或者用以前加載也能夠,當和extend同時使用時,放在entend下面)
{% load my_tags %} # 這裏的名字就是咱們建立的my_tags.py的文件名
調用
{{ hello|multi:2 }} # hello 表示傳遞的第一個參數,2表示傳遞的是第二個參數,冒號後面必需要緊跟傳遞的參數,多一個空格都不行
PS:filter 的函數只能接受一個額外參數(兩個參數,默認會把要處理的對象看成第一個參數,第二個參數是咱們須要傳遞的參數),能夠用於if/for等語句的條件,渲染時 使用 {{ 參數1 | xxx:參數2 }} 渲染 。
simpletag與filter不一樣的是,能夠接受多個參數,但不能夠用if/for等語句的條件,使用 {% xxx %} 渲染,建立步驟與filter相同
編寫simpletag
# my_tags.py文件 from django import template # 須要先導入文件 register = template.Library() # register的名字是固定的,不可改變,由於下面會進行調用 @register.simple_tag # 必需要裝飾咱們自定義的函數才行 def simple_tag_multi(num1,num2): return num1 * num2
加載完畢後調用方式使用 {% %}
{% simple_tag_multi 10 20 %} # 參數以空格隔開,多個空格效果相同
循環等邏輯語句須要使用{% %} 來進行渲染
{% for i in li %} # li 爲後端傳遞給模板的變量 <p>{{ i }}</p> {% endfor %} #使用endfor來表示循環結束
在for循環中存在一個forloop變量,該變量記錄循環相關數據
reversed和empty:
reversed
:對可迭代對象進行逆序empty
:若是可迭代對象爲空{% for athlete in athlete_list reversed %} ... {% empty %} ... 若是被迭代的列表是空的或者不存在,執行empty {% endfor %}
{% if li.1 > 100 %} <p> 大於 </p> {% elif li.1 < 100 %} <p> 小於 </p> {% else %} <p> 等於 </p> {% endif %} #使用endif來表示條件判斷結束
{% 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 %}
{% url 'varname' %}
:引用路由配置的地址
<form action="{% url "LOGIN"%}" method="POST"> # 路由引用 <input type="text"> <input type="submit" value="提交"> </form>
{% verbatim %}
:禁止render解析。
既在有的時候咱們僅僅只是想打印出 {{ hello }} 而已,使用verbatim來禁止render進行解析
{% verbatim %} {{ hello }} {% endverbatim %} # 使用verbatim 包起來的代碼 將不會進行解析
{% csrf_token %}
:用於跨站請求僞造保護,防止跨站攻擊的。
<form> {% csrf_token %} </form>
通常用在form表單中。
到目前爲止,咱們的模板範例都只是些零星的 HTML 片斷,但在實際應用中,你將用 Django 模板系統來建立整個 HTML 頁面。 這就帶來一個常見的 Web 開發問題: 在整個網站中,如何減小共用頁面區域(好比站點導航)所引發的重複和冗餘代碼?Django 解決此類問題的首選方法是使用一種優雅的策略 —— 模板繼承
.
本質上來講,模板繼承就是先構造一個基礎框架模板,然後在其子模板中對它所包含站點公用部分和定義塊進行重載.
編寫模板須要使用模板標籤:
{% block name%} {% endblock %}
:全部的 {% block %} 標籤告訴模板引擎,子模板能夠重載這些部分。 每一個{% block %}標籤所要作的是告訴模板引擎,該模板下的這一塊內容將有可能被子模板覆蓋。
下面是一個html模板文件:
// index.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div class="title"></div> <div class="left"> <div class="left_list"> <a href="/booklist/">文章列表</a> </div> </div> <div class="right"> {% block content %} // 這裏定義content,表示這裏能夠被繼承模板進行替換 {% endblock %} // 包起來的表示代碼段 </div> </body> </html>
HTML中包含 block 語句塊的均可以稱爲模板文件
子模板進行繼承,並定製本身要顯示的內容(子模板不須要額外的html代碼,其代碼都來自於模板文件),僅僅須要定義 block塊內的信息便可,固然也能夠不定義,或者在block塊中調用父模板的內容。
// test.html {% extends 'index.html' %} // 繼承模板文件 {% block content %} // 針對模板中content的代碼塊進行定義 <h1>hello world</h1> <h1>hello world</h1> <h1>hello world</h1> <h1>hello world</h1> <h1>hello world</h1> <h1>hello world</h1> {% endblock %}
使用注意:
第一個
模板標記(html首部
)。 不然,模板繼承將不起做用。{{ block.super }}
這個標籤吧,這一個魔法變量將會表現出父模板中的內容。 若是隻想在上級代碼塊基礎上添加內容,而不是所有重載,該變量就顯得很是有用了。一個html文件只能引入一個模版
在不少網站中,基本上的都會有一個開頭和一個結尾,在每個網頁中都會顯示。相對於這種的來講,在Django中,最好的方法就是使用include的標籤,在每個模板中都加入這個開頭和結尾的標籤。
簡單來講,就是那些多個頁面都須要的公共標籤放在一個統一的html文件,供其餘html文件引入。
{% include 'tpl.html' %} : 表示引入tpl.html文件。
看下面的例子:
# -------------------- tpl.html -------------------- <div> <h1>hello world</h1> </div> # -------------------- xxx.html -------------------- ... <div> {% include 'tpl.html' %} {% include 'tpl.html' %} // tpl.html的所有內容會在這裏填充 ... </div> ...
在一個頁面中能夠經過include引入不一樣的公共組件。