直接將HTML硬編碼到視圖裏並非一個好主意。 讓咱們來看一下爲何:css
from django.shortcuts import render,HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = '<html><body>It is now %s</body></html>' % now return HttpResponse(html)
對頁面設計進行的任何改變都必須對 Python 代碼進行相應的修改。 站點設計的修改每每比底層 Python 代碼的修改要頻繁得多,所以若是能夠在不進行 Python 代碼修改的狀況下變動設計,那將會方便得多。html
Python 代碼編寫和 HTML 設計是兩項不一樣的工做,大多數專業的網站開發環境都將他們分配給不一樣的人員(甚至不一樣部門)來完成。 設計者和HTML/CSS的編碼人員不該該被要求去編輯Python的代碼來完成他們的工做。python
程序員編寫 Python代碼和設計人員製做模板兩項工做同時進行的效率是最高的,遠勝於讓一我的等待另外一我的完成對某個既包含 Python又包含 HTML 的文件的編輯工做。程序員
基於這些緣由,將頁面的設計和Python的代碼分離開會更乾淨簡潔更容易維護。 咱們可使用 Django的 模板系統 (Template System)來實現這種模式數據庫
python的模板:HTML代碼+模板語法django
def current_time(req): # ================================原始的視圖函數 # import datetime # now=datetime.datetime.now() # html="<html><body>如今時刻:<h1>%s.</h1></body></html>" %now # ================================django模板修改的視圖函數 # from django.template import Template,Context # now=datetime.datetime.now() # t=Template('<html><body>如今時刻是:<h1>{{current_date}}</h1></body></html>') # #t=get_template('current_datetime.html') # c=Context({'current_date':str(now)}) # html=t.render(c) # # return HttpResponse(html) #另外一種寫法(推薦) import datetime now=datetime.datetime.now() return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})
模板語法
1.渲染變量{{ }}
1.深度查詢 句點符
語法:{{var_name}}
<p>{{ alex.age }}</p>
<p>{{ person_list.1.age }}</p>
2.過濾器
語法:{{obj|filter__name:param}}
按照某種形式渲染出來
<p>{{ now|date:'Y-m-d' }}</p>
<p>{{ info.name|upper }}</p>
2.渲染標籤{% %}
語法:{% tag %}
...
示例:bootstrap
views.py緩存
from django.shortcuts import render,HttpResponse def index(request): #============================模板語法之變量=================================== import datetime s = 'hello' li = [111,222,333] dic = {'name':'alce','age':22} date = datetime.date(2018,5,21) class Person(object): def __init__(self,name): self.name = name person_yuan = Person('yuan') person_alex = Person('alex') person_egon = Person('egon') person_list = [person_yuan,person_alex,person_egon] # return render(request,'index.html',{'s':s}) # 全部得變量都會傳到模板中 return render(request,'index.html',locals())
index.html安全
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <h3>模板語法之變量</h3> <p>{{ s }}</p> <p>{{ li }}</p> <p>{{ li.1 }}</p> <p>{{ dic }}</p> <p>{{ dic.name }}</p> <p>{{ date }}</p> <p>{{ date.year }}</p> <p>{{ person_alex }}</p> <p>{{ person_alex.name }}</p> <p>{{ person_list }}</p> <p>{{ person_list.1.name }}</p> <p>{{ person_list.1.name.upper }}</p> # 句點符也能夠用來引用對象的方法(無參數方法): </body> </html>
default
app
若是一個變量是false或者爲空,使用給定的默認值。不然,使用變量的值。例如
{{ value|default:
"nothing"
}}
length
返回值的長度。它對字符串和列表都起做用。例如:
{{ value|length }}
若是 value 是 ['a', 'b', 'c', 'd'],那麼輸出是 4。
filesizeformat
將值格式化爲一個 「人類可讀的」 文件尺寸 (例如 '13 KB'
, '4.1 MB'
, '102 bytes'
, 等等)。例如:
{{ value|filesizeformat }}
若是 value
是 123456789,輸出將會是 117.7 MB
。
date
若是 value=datetime.datetime.now()
{{ value|date:
"Y-m-d"
}}
slice
若是 value="hello world"
{{ value|
slice
:
"2:-1"
}}
若是字符串字符多於指定的字符數量,那麼會被截斷。截斷的字符串將以可翻譯的省略號序列(「...」)結尾。
參數:要截斷的字符數
例如:
{{ value|truncatechars:
9
}}
safe
Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統,後臺添加的文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本,若是自動轉義的話顯示的就是保護HTML標籤的源文件。爲了在Django中關閉HTML的自動轉義有兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的沒必要轉義。好比:
value
=
"<a href="
">點擊</a>"
{{ value|safe}}
簡單介紹一些經常使用的模板的過濾器: ... ...
標籤看起來像是這樣的: {% tag %}
。標籤比變量更加複雜:一些在輸出中建立文本,一些經過循環或邏輯來控制流程,一些加載其後的變量將使用到的額外信息到模版中。一些標籤須要開始和結束標籤 (例如{% tag %} ...
標籤 內容 ... {% endtag %})。
for標籤
遍歷每個元素:
{% for person in person_list %} <p>{{ person.name }}</p> {% endfor %}
能夠利用{% for obj in list reversed %}反向完成循環。
遍歷一個字典:
{% for key,val in dic.items %} <p>{{ key }}:{{ val }}</p> {% endfor %}
注:循環序號能夠經過{{forloop}}顯示
forloop.counter The current iteration of the loop (1-indexed) forloop.counter0 The current iteration of the loop (0-indexed) forloop.revcounter The number of iterations from the end of the loop (1-indexed) forloop.revcounter0 The number of iterations from the end of the loop (0-indexed) forloop.first True if this is the first time through the loop forloop.last True if this is the last time through the loop
for 標籤帶有一個可選的{% empty %} 從句,以便在給出的組是空的或者沒有被找到時,能夠有所操做。
{% for person in person_list %} <p>{{ person.name }}</p> {% empty %} <p>sorry,no person here</p> {% endfor %}
if 標籤
{% if %}會對一個變量求值,若是它的值是「True」(存在、不爲空、且不是boolean類型的false值),對應的內容塊會輸出。
{% if num > 100 or num < 0 %} <p>無效</p> {% elif num > 80 and num < 100 %} <p>優秀</p> {% else %} <p>湊活吧</p> {% endif %}
with
使用一個簡單地名字緩存一個複雜的變量,當你須要使用一個「昂貴的」方法(好比訪問數據庫)不少次的時候是很是有用的
例如:
{% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %}
{# 深度查詢 很是長得 時候 能夠用with #}
{% with person_list.1.name as n %}
{{ n }}
{{ n }}
{% endwith %}
這個標籤用於跨站請求僞造保護
爲了保留django 留給咱們得 安全機制 django 得中間見
只要發 post 請求 ,{ % csrf_token %} 爲了安全機制
{ % csrf_token %} 解決辦法
< input
type = 'hidden'
name = 'csrfmiddlewaretoken'
value = 'OqNwoXIbFSTI3qxdtqKppQuZvlWebFgw9vSAkGXrGX4J2wo9t7OWDXvyxU4asBRE' / >
一、在settings中的INSTALLED_APPS配置當前app,否則django沒法找到自定義的simple_tag.
二、在app中建立templatetags模塊(模塊名只能是templatetags)
三、建立任意 .py 文件,如:my_tag_filter.py
from django import template from django.utils.safestring import mark_safe # register的名字是固定的,不可改變 register = template.Library() # 自定義過濾器 @register.filter def multi_filter(x,y): return x*y # 自定義標籤 @register.simple_tag def multi_tags(x,y,z): return x*y*z @register.simple_tag def my_input(id,arg): result = "<input type='text' id='%s' class='%s' />" %(id,arg,) return mark_safe(result)
四、在使用自定義simple_tag和filter的html文件中導入以前建立的 my_tag_filter.py
{% load my_tag_filter %}
五、使用simple_tag和filter(如何調用)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <h3>自定義標籤 過濾器</h3> {% load my_tag_filter %} {# num = 4 8 #} {{ num|multi_filter:2 }} {# 2*3*4 = 24 #} {# 參數不限,但不能放在if for語句中 #} {% multi_tags 2 3 4 %} {% if num|multi_filter:2 > 20 %} {{ num|multi_filter:2 }} {% else %} {{ num }} {% endif %} {# 注意:filter能夠用在if等語句後,tag不能夠 #} {% my_input 2 'active' %} </body> </html>
注意:filter能夠用在if等語句後,simple_tag不能夠
{% if num|multi_filter:2 > 20 %}
{{ num|multi_filter:2 }}
{% else %}
{{ num }}
{% endif %}
Django模版引擎中最強大也是最複雜的部分就是模版繼承了。模版繼承可讓您建立一個基本的「骨架」模版,它包含您站點中的所有元素,而且能夠定義可以被子模版覆蓋的 blocks 。
經過從下面這個例子開始,能夠容易的理解模版繼承:
base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> {% block title %} <title>base</title> {% endblock %} <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <style type="text/css"> *{padding: 0;margin: 0;} .header{ width: 100%;height: 50px;background-color: #369} </style> </head> <body> <div class="header"></div> <div class="container"> <div class="col-md-3"> {% include 'advertise.html' %} </div> <div class="col-md-9"> {% block con %} <h1>content</h1> {% endblock %} </div> </div> </body> </html>
這個模版,咱們把它叫做 base.html
, 它定義了一個能夠用於兩列排版頁面的簡單HTML骨架。「子模版」的工做是用它們的內容填充空的blocks。
在這個例子中, block
標籤訂義了三個能夠被子模版內容填充的block。 block
告訴模版引擎: 子模版可能會覆蓋掉模版中的這些位置。
子模版可能看起來是這樣的:
{% extends "base.html" %} {% block title %}My amazing blog{% endblock %} {% block content %} {% for entry in blog_entries %} <h2>{{ entry.title }}</h2> <p>{{ entry.body }}</p> {% endfor %} {% endblock %}
extends
標籤是這裏的關鍵。它告訴模版引擎,這個模版「繼承」了另外一個模版。當模版系統處理這個模版時,首先,它將定位父模版——在此例中,就是「base.html」。
那時,模版引擎將注意到 base.html
中的三個 block
標籤,並用子模版中的內容來替換這些block。根據 blog_entries
的值,輸出可能看起來是這樣的:
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="style.css" /> <title>My amazing blog</title> </head> <body> <div id="sidebar"> <ul> <li><a href="/">Home</a></li> <li><a href="/blog/">Blog</a></li> </ul> </div> <div id="content"> <h2>Entry one</h2> <p>This is my first entry.</p> <h2>Entry two</h2> <p>This is my second entry.</p> </div> </body> </html>
請注意,子模版並無定義 sidebar
block,因此係統使用了父模版中的值。父模版的 {% block %}
標籤中的內容老是被用做備選內容(fallback)。
這種方式使代碼獲得最大程度的複用,而且使得添加內容到共享的內容區域更加簡單,例如,部分範圍內的導航。
這裏是使用繼承的一些提示:
若是你在模版中使用 {% extends %}
標籤,它必須是模版中的第一個標籤。其餘的任何狀況下,模版繼承都將沒法工做。
在base模版中設置越多的 {% block %}
標籤越好。請記住,子模版沒必要定義所有父模版中的blocks,因此,你能夠在大多數blocks中填充合理的默認內容,而後,只定義你須要的那一個。多一點鉤子總比少一點好。
若是你發現你本身在大量的模版中複製內容,那可能意味着你應該把內容移動到父模版中的一個 {% block %}
中。
If you need to get the content of the block from the parent template, the {{ block.super }}
variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using {{ block.super }}
will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.
爲了更好的可讀性,你也能夠給你的 {% endblock %}
標籤一個 名字 。例如:
{% block content %}
...
{% endblock content %}
在大型模版中,這個方法幫你清楚的看到哪個 {% block %}
標籤被關閉了。
block
標籤。
示例: