python自動化運維學習第十八天--template
template
template就是模板,在html程式碼中嵌入邏輯控制程式碼。
template支援的語法
變數
語法格式: {{var_name}}
----------------------------------Template和Context物件
>>> python manange.py shell (進入該django專案的環境)
>>> from django.template import Context, Template
>>> t = Template('My name is {{ name }}.' )
>>> c = Context({'name': 'Stephane'})
>>> t.render(c)
'My name is Stephane.'
# 同一模板,多個上下文,一旦有了模板物件,你就可以通過它渲染多個context,無論何時我們都可以
# 像這樣使用同一模板源渲染多個context,只進行 一次模板建立然後多次呼叫render()方法渲染會
# 更為高效:
# Low
for name in ('John', 'Julie', 'Pat'):
t = Template('Hello, {{ name }}')
print t.render(Context({'name': name}))
# Good
t = Template('Hello, {{ name }}')
for name in ('John', 'Julie', 'Pat'):
print t.render(Context({'name': name}))
變數查詢
使用句點號(.)
#最好是用幾個例子來說明一下。
# 首先,句點可用於訪問列表索引,例如:
>>> from django.template import Template, Context
>>> t = Template( 'Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
'Item 2 is carrots.'
#假設你要向模板傳遞一個 Python 字典。 要通過字典鍵訪問該字典的值,可使用一個句點:
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
'Sally is 43 years old.'
#同樣,也可以通過句點來訪問物件的屬性。 比方說, Python 的 datetime.date 物件有
#year 、 month 和 day 幾個屬性,你同樣可以在模板中使用句點來訪問這些屬性:
>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1993, 5, 2)
>>> d.year
>>> d.month
>>> d.day
>>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')
>>> c = Context({'date': d})
>>> t.render(c)
'The month is 5 and the year is 1993.'
# 這個例子使用了一個自定義的類,演示了通過例項變數加一點(dots)來訪問它的屬性,這個方法適
# 用於任意的物件。
>>> from django.template import Template, Context
>>> class Person(object):
... def __init__(self, first_name, last_name):
... self.first_name, self.last_name = first_name, last_name
>>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
'Hello, John Smith.'
# 點語法也可以用來引用物件的方法。 例如,每個 Python 字串都有 upper() 和 isdigit()
# 方法,你在模板中可以使用同樣的句點語法來呼叫它們:
>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
'123 -- 123 -- True'
# 注意這裡呼叫方法時並* 沒有* 使用圓括號 而且也無法給該方法傳遞引數;你只能呼叫不需引數的
# 方法。
變數的過濾(filter)
語法格式: {{obj|filter:param}}
# 1 add : 給變數加上相應的值
# 2 addslashes : 給變數中的引號前加上斜線
# 3 capfirst : 首字母大寫
# 4 cut : 從字串中移除指定的字元
# 5 date : 格式化日期字串
# 6 default : 如果值是False,就替換成設定的預設值,否則就是用本來的值
# 7 default_if_none: 如果值是None,就替換成設定的預設值,否則就使用本來的值
#例項:
#value1="aBcDe"
{{ value1|upper }}<br> #輸出ABCDE
#value2=5
{{ value2|add:3 }}<br> #輸出8
#value3='he llo wo r ld'
{{ value3|cut:' ' }}<br> #輸出helloworld
#import datetime
#value4=datetime.datetime.now()
{{ value4|date:'Y-m-d' }}<br> #輸出2018-12-20
#value5=[]
{{ value5|default:'空的' }}<br>
#value6='<a href="#">跳轉</a>'
{{ value6 }}
{% autoescape off %}
{{ value6 }}
{% endautoescape %}
{{ value6|safe }}<br>
{{ value6|striptags }}
#value7='1234'
{{ value7|filesizeformat }}<br>
{{ value7|first }}<br>
{{ value7|length }}<br>
{{ value7|slice:":-1" }}<br>
#value8='http://www.baidu.com/?a=1&b=3'
{{ value8|urlencode }}<br>
value9='hello I am yuan'
標籤(simple_tag)的使用
語法格式: {% tags %}
{% if %} 的使用
{% if %}標籤計算一個變數值,如果是“true”,即它存在、不為空並且不是false的boolean值,系統則會顯示{% if %}和{% endif %}間的所有內容
{% if num >= 100 and 8 %}
{% if num > 200 %}
<p>num大於200</p>
{% else %}
<p>num大於100小於200</p>
{% endif %}
{% elif num < 100%}
<p>num小於100</p>
{% else %}
<p>num等於100</p>
{% endif %}
{% if %} 標籤接受and,or或者not來測試多個變數值或者否定一個給定的變數
{% if %} 標籤不允許同一標籤裡同時出現and和or,否則邏輯容易產生歧義,例如下面的標籤是不合法的:
{% if obj1 and obj2 or obj3 %}
{% for %}的使用
{% for %}標籤允許你按順序遍歷一個序列中的各個元素,每次迴圈模板系統都會渲染{% for %}和{% endfor %}之間的所有內容
<ul>
{% for obj in list %}
<li>{{ obj.name }}</li>
{% endfor %}
</ul>
#在標籤裡新增reversed來反序迴圈列表:
{% for obj in list reversed %}
...
{% endfor %}
#{% for %}標籤可以巢狀:
{% for country in countries %}
<h1>{{ country.name }}</h1>
<ul>
{% for city in country.city_list %}
<li>{{ city }}</li>
{% endfor %}
</ul>
{% endfor %}
#系統不支援中斷迴圈,系統也不支援continue語句,{% for %}標籤內建了一個forloop模板變數,
#這個變數含有一些屬性可以提供給你一些關於迴圈的資訊
1,forloop.counter表示迴圈的次數,它從1開始計數,第一次迴圈設為1:
{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
2,forloop.counter0 類似於forloop.counter,但它是從0開始計數,第一次迴圈設為0
3,forloop.revcounter
4,forloop.revcounter0
5,forloop.first當第一次迴圈時值為True,在特別情況下很有用:
{% for object in objects %}
{% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
{{ object }}
</li>
{% endfor %}
# 富有魔力的forloop變數只能在迴圈中得到,當模板解析器到達{% endfor %}時forloop就消失了
# 如果你的模板context已經包含一個叫forloop的變數,Django會用{% for %}標籤替代它
# Django會在for標籤的塊中覆蓋你定義的forloop變數的值
# 在其他非迴圈的地方,你的forloop變數仍然可用
#{% empty %}
{{li }}
{% for i in li %}
<li>{{ forloop.counter0 }}----{{ i }}</li>
{% empty %}
<li>this is empty!</li>
{% endfor %}
# [11, 22, 33, 44, 55]
# 0----11
# 1----22
# 2----33
# 3----44
# 4----55
{% url %}
引用路由配置的地址
<form action="{% url "bieming"%}" >
<input type="text">
<input type="submit"value="提交">
{%csrf_token%}
</form>
{% with %}
用更簡單的變數名替代複雜的變數名
{% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}
{% verbatim %}
禁止render
{% verbatim %}
{{ hello }}
{% endverbatim %}
自定義filter和simple_tag
- 在app中建立templatetags包(必須,名字不能改)
- 在templatetags建立任意 .py 檔案,如:my_tags.py
from django.template import Library
register = Library() #register的名字是固定的,不可改變
@register.filter
def filter_multi(v1,v2):
return v1 * v2
@register.simple_tag
def simple_tag(v1,v2):
return v1 * v2
@register.simple_tag
def simple_tag_multi(v1,v2,v3,v4):
return v1 * v2 * v3 * v4
- 在使用自定義simple_tag和filter的html檔案中匯入之前建立的 my_tags.py :{% load my_tags %}
- 使用simple_tag和filter(如何呼叫)
-------------------------------.html
{% load xxx %} #首行
# num=12
{{ num|filter_multi:2 }} #24
{{ num|filter_multi:"[22,333,4444]" }}
{% simple_tag_multi 2 5 4 5 %} 引數不限,但不能放在if for語句中
{% simple_tag num 5 %}
- 在settings中的INSTALLED_APPS配置當前app,不然django無法找到自定義的simple_tag.
注意:
filter可以用在if等語句後,simple_tag不可以
{% if num|filter_multi:30 > 100 %}
{{ num|filter_multi:30 }}
{% endif %}
extend模板繼承
模板繼承就是先構造一個基礎框架模板,而後在其子模板中對它所包含站點公用部分和定義塊進行過載。
定義基礎模板(base.html),該框架之後將由子模板所繼承。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>My helpful timestamp site</h1>
{% block content %}{% endblock %}
{% block footer %}
<hr>
<p>Thanks for visiting my site.</p>
{% endblock %}
</body>
</html>
使用模板標籤: {% block %} 。
所有的 {% block %} 標籤告訴模板引擎,子模板可以過載這部分。 每個{% block %}標籤所要做的是告訴模板引擎,該模板下的這一塊內容將有可能被子模板覆蓋。
新建current_datetime.html 模板來使用base.html模板:
{% extends "base.html" %}
{% block title %}The current time{% endblock %}
{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}
繼承模板的工作方式:在載入 current_datetime.html 模板時,模板引擎發現了 {% extends %} 標籤, 注意到該模板是一個子模板。 模板引擎立即裝載其父模板,即本例中的 base.html 。此時,模板引擎注意到 base.html 中的三個 {% block %} 標籤,並用子模板的內容替換這些 block 。因此,引擎將會使用我們在 { block title %} 中定義的標題,對 {% block content %} 也是如此。 所以,網頁標題一塊將由{% block title %}替換,同樣地,網頁的內容一塊將由 {% block content %}替換。
注意:由於子模板並沒有定義 footer 塊,模板系統將使用在父模板中定義的值。 父模板 {% block %} 標籤中的內容總是被當作一條退路。繼承並不會影響到模板的上下文。 換句話說,任何處在繼承樹上的模板都可以訪問到你傳到模板中的每一個模板變數。你可以根據需要使用任意多的繼承次數。
使用繼承的一種常見方式是下面的三層法:
<1> 建立 base.html 模板,在其中定義站點的主要外觀感受。 這些都是不常修改甚至從不修改的部分。
<2> 為網站的每個區域建立 base_SECTION.html 模板(例如, base_photos.html 和 base_forum.html )。這些模板對base.html 進行拓展,幷包含區域特定的風格與設計。
<3> 為每種型別的頁面建立獨立的模板,例如論壇頁面或者圖片庫。 這些模板拓展相應的區域模板。
使用模板的一些訣竅
<1>如果在模板中使用 {% extends %} ,必須保證其為模板中的第一個模板標記。 否則,模板繼承將不起作用。
<2>一般來說,基礎模板中的 {% block %} 標籤越多越好。 記住,子模板不必定義父模板中所有的程式碼塊,因此你可以用合理的預設值對一些程式碼塊進行填充,然後只對子模板所需的程式碼塊進行(重)定義。俗話說,鉤子越多越好。
<3>如果發覺自己在多個模板之間拷貝程式碼,你應該考慮將該程式碼段放置到父模板的某個 {% block %} 中。如果你需要訪問父模板中的塊的內容,使用 {{ block.super }}這個標籤吧,這一個魔法變數將會表現出父模板中的內容。 如果只想在上級程式碼塊基礎上新增內容,而不是全部過載,該變數就顯得非常有用了。
<4>不允許在同一個模板中定義多個同名的 {% block %} 。 存在這樣的限制是因為block 標籤的工作方式是雙向的。也就是說,block 標籤不僅挖了一個要填的坑,也定義了在父模板中這個坑所填充的內容。如果模板中出現了兩個相同名稱的 {% block %} 標籤,父模板將無從得知要使用哪個塊的內容。
引用靜態檔案
如果在專案中使用一些靜態檔案,如js、css等,可以在專案下建立一個static的目錄,用來統一存放這些靜態檔案。放到static目錄下,如何來引用這些檔案。加入有一個sample.js的檔案,放到static目錄下了。
首先在settings.py檔案中最後一行新增一段程式碼
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static/"), #靜態檔案放在專案下的static目錄下
#os.path.join(BASE_DIR, "demo/static/"), #靜態檔案放在專案下的demo這個app下的static目錄下
)
然後修改login.html檔案,即引用js的html檔案
在檔案第一行新增一行程式碼
{% load staticfiles %}
在引用的部分新增如下程式碼
<script src="{% static 'sample.js' %}"></script>
這樣就可以引用sample.js這個檔案了