爲何用templates?css
views.py視圖函數是用來寫Python代碼的,HTML能夠被直接硬編碼在views.py之中。以下:html
import datetime def current_time(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
對頁面設計進行的任何改變都必須對 Python views.py中的代碼進行相應的修改。 站點設計的修改每每比底層 Python 代碼的修改要頻繁得多,所以若是能夠在不進行 Python 代碼修改的狀況下變動設計,那將會方便得多。python
Python 代碼編寫和 HTML 設計是兩項不一樣的工做,大多數專業的網站開發環境都將他們分配給不一樣的人員(甚至不一樣部門)來完成。 設計者和HTML/CSS的編碼人員不該該被要求去編輯Python的代碼來完成他們的工做。jquery
程序員編寫 Python代碼和設計人員製做模板兩項工做同時進行的效率是最高的,遠勝於讓一我的等待另外一我的完成對某個既包含 Python又包含 HTML 的文件的編輯工做。git
基於這些緣由,將頁面的設計和Python的代碼分離開會更乾淨簡潔更容易維護。 咱們可使用 Django的 模板系統 (Template System)來實現這種模式。程序員
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
2.templates模板組成shell
HTML代碼+邏輯控制代碼django
你使用過一些在HTML中直接混入程序代碼的語言,如今,Django的模版系統並非簡單的將Python嵌入到HTML中。數據結構
設計決定了:模版系統致力於表達外觀,而不是程序邏輯。架構
Django的模版系統提供了和某些程序架構相似的標籤——用於布爾判斷的 if 標籤, 用於循環的 for 標籤等等。
——可是這些都不是簡單的做爲Python代碼那樣來執行的,而且,模版系統也不會隨意執行Python表達式。
只有下面列表中的標籤、過濾器和語法纔是默認就被支持的。(可是您也能夠根據須要添加您本身的擴展到模版語言中)。
變量: {{ variable }}
點號(.)用來訪問變量的屬性。
當模版系統遇到點("."),它將以這樣的順序查詢:
>>> python manange.py shell (進入該django項目的環境) >>> from django.template import Context, Template >>> t = Template('My name is {{ name }}.') >>> c = Context({'name': 'Gregory'}) >>> t.render(c) 'My name is Gregory.'
同一模板,多個上下文,一旦有了模板對象,你就能夠經過它渲染多個context,不管什麼時候咱們均可以,像這樣使用同一模板源渲染多個context,只進行 一次模板建立而後屢次調用render()方法渲染會 更爲高效:
t = Template('Hello, {{ name }}') for name in ('John', 'Julie', 'Pat'): print(t.render(Context({'name': name})))
在 Django 模板中遍歷複雜數據結構的關鍵是句點字符 (.)
1 #最好是用幾個例子來講明一下。 2 # 首先,句點可用於訪問列表索引,例如: 3 4 >>> from django.template import Template, Context 5 >>> t = Template('Item 2 is {{ items.2 }}.') 6 >>> c = Context({'items': ['apples', 'bananas', 'carrots']}) 7 >>> t.render(c) 8 'Item 2 is carrots.' 9 10 #假設你要向模板傳遞一個 Python 字典。 要經過字典鍵訪問該字典的值,可以使用一個句點: 11 >>> from django.template import Template, Context 12 >>> person = {'name': 'Sally', 'age': '43'} 13 >>> t = Template('{{ person.name }} is {{ person.age }} years old.') 14 >>> c = Context({'person': person}) 15 >>> t.render(c) 16 'Sally is 43 years old.' 17 18 #一樣,也能夠經過句點來訪問對象的屬性。 比方說, Python 的 datetime.date 對象有 19 #year 、 month 和 day 幾個屬性,你一樣能夠在模板中使用句點來訪問這些屬性: 20 21 >>> from django.template import Template, Context 22 >>> import datetime 23 >>> d = datetime.date(1993, 5, 2) 24 >>> d.year 25 1993 26 >>> d.month 27 5 28 >>> d.day 29 2 30 >>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.') 31 >>> c = Context({'date': d}) 32 >>> t.render(c) 33 'The month is 5 and the year is 1993.' 34 35 # 這個例子使用了一個自定義的類,演示了經過實例變量加一點(dots)來訪問它的屬性,這個方法適 36 # 用於任意的對象。 37 >>> from django.template import Template, Context 38 >>> class Person(object): 39 ... def __init__(self, first_name, last_name): 40 ... self.first_name, self.last_name = first_name, last_name 41 >>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.') 42 >>> c = Context({'person': Person('John', 'Smith')}) 43 >>> t.render(c) 44 'Hello, John Smith.' 45 46 # 點語法也能夠用來引用對象的方法。 例如,每一個 Python 字符串都有 upper() 和 isdigit() 47 # 方法,你在模板中可使用一樣的句點語法來調用它們: 48 >>> from django.template import Template, Context 49 >>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}') 50 >>> t.render(Context({'var': 'hello'})) 51 'hello -- HELLO -- False' 52 >>> t.render(Context({'var': '123'})) 53 '123 -- 123 -- True' 54 55 # 注意這裏調用方法時並* 沒有* 使用圓括號 並且也沒法給該方法傳遞參數;你只能調用不需參數的 56 # 方法。
您能夠經過使用 過濾器來改變變量的顯示。
{{ name|lower }}。這將在變量 {{ name }} 被過濾器 lower 過濾後再顯示它的值,該過濾器將文本轉換成小寫。使用管道符號 (|)來應用過濾器。
過濾管道能夠被* 套接* ,既是說,一個過濾器管道的輸出又能夠做爲下一個管道的輸入:
{{ my_list|first|upper }} 將第一個元素並將其轉化爲大寫。
add——把add後的參數加給value
{{ value|add:"2" }} 若是 value 爲 4,則會輸出 6. 過濾器首先會強制把兩個值轉換成Int類型。若是強制轉換失敗, 它會試圖使用各類方式吧兩個值相加。它會使用一些數據類型 (字符串, 列表, 等等.)
{{ value|last }} If value is the list ['a', 'b', 'c', 'd'], the output will be the string "d".
{{ value|length }}若是value是['a', 'b', 'c', 'd']或"abcd",輸出將爲4。
1 add : 給變量加上相應的值 2 addslashes : 給變量中的引號前加上斜線 3 capfirst : 首字母大寫 4 cut : 從字符串中移除指定的字符 5 date : 格式化日期字符串 6 default : 若是值是False,就替換成設置的默認值,不然就是用原本的值 7 default_if_none: 若是值是None,就替換成設置的默認值,不然就使用原本的值
{% for %} 容許咱們在一個序列上迭代。
{% for a in a_list %} <li>{{ a.name }}</li> {% endfor %}
根據條件判斷是否輸出。if/else 支持嵌套。{% if %} 標籤接受 and , or 或者 not 關鍵字來對多個變量作判斷 ,或者對變量取反( not ),例如:
{% if a_list and c_list %} a 和 c變量都是可用的。 {% endif %}
註釋標籤——要註釋模版中一行的部份內容,使用註釋語法 {# #}.
{%csrf_token%}:csrf_token標籤
用於生成csrf_token的標籤,用於防治跨站攻擊驗證。注意若是你在view的index裏用的是render_to_response方法,不會生效
其實,這裏是會生成一個input標籤,和其餘表單標籤一塊兒提交給後臺的。
<form action="{% url "bieming"%}" > <input type="text"> <input type="submit"value="提交"> {%csrf_token%} </form>
{% url %}: 引用路由配置的地址
{% with %}:用更簡單的變量名替代複雜的變量名
{% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}
{% verbatim %}: 禁止render
{% verbatim %}
{{ hello }}
{% endverbatim %}
{% load %}: 加載標籤庫
{% include %} 標籤容許在模板中包含其它的模板的內容。
2.4 自定義模板標籤和過濾器
a、在app中建立templatetags模塊(必須的)
app/ __init__.py models.py templatetags/ __init__.py mytag.py views.py
使用{% load mytag %}
b、建立任意 .py 文件,如:mytag.py
爲了成爲一個可用的標籤庫,這個模塊必須包含一個名爲 register的變量,它是template.Library 的一個實例,全部的標籤和過濾器都是在其中註冊的。因此把以下的內容放在你的模塊的頂部:
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
@register.filter def filter_multi(v1,v2): return v1 * v2 @register.simple_tag def simple_tag_multi(v1,v2): return v1 * v2 @register.simple_tag def my_input(id,arg): result = "<input type='text' id='%s' class='%s' />" %(id,arg,) return mark_safe(result)
c、在使用自定義simple_tag和filter的html文件中導入以前建立的 my_tags.py :{% load mytag %}
d、使用simple_tag和filter(如何調用)
{% load xxx %} #首行 # num=12 {{ num|filter_multi:2 }} #24 {{ num|filter_multi:"[22,333,4444]" }} {% simple_tag_multi 2 5 %} 參數不限,但不能放在if for語句中 {% simple_tag_multi num 5 %}
模版繼承可讓您建立一個基本的「骨架」模版,它包含您站點中的所有元素,而且能夠定義可以被子模版覆蓋的 blocks 。
base.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 body{ 8 margin: 0; 9 } 10 .hide{ 11 display: none; 12 } 13 .menu .item{ 14 display: block; 15 padding: 5px 10px; 16 border-bottom: 1px solid #dddddd; 17 } 18 .menu .item:hover{ 19 background-color: black; 20 color: white; 21 } 22 .menu .item.active{ 23 background-color: black; 24 color: white; 25 } 26 27 .modal{ 28 position: fixed; 29 top: 50%; 30 left: 50%; 31 width: 500px; 32 height: 400px; 33 margin-top: -250px; 34 margin-left: -250px; 35 z-index: 100; 36 background-color: white; 37 } 38 .remove{ 39 position: fixed; 40 top: 50%; 41 left: 50%; 42 width: 400px; 43 height: 200px; 44 margin-top: -100px; 45 margin-left: -200px; 46 z-index: 100; 47 background-color: #c00; 48 } 49 .shade{ 50 position: fixed; 51 top: 0; 52 left: 0; 53 right: 0; 54 bottom: 0; 55 background-color: black; 56 opacity: 0.5; 57 z-index: 99; 58 } 59 .pagination a{ 60 display: inline-block; 61 padding: 5px; 62 } 63 .pagination a.active{ 64 background-color: black; 65 color: white; 66 } 67 </style> 68 {% block css %} {% endblock %} 69 </head> 70 <body> 71 <div style="height: 48px;background-color: black;color: white"> 72 <div style="float: right">用戶名:{{ username }} | <a href="/logout.html">註銷</a></div> 73 </div> 74 75 <div> 76 <div class="menu" style="position: absolute;top: 48px;left: 0;bottom:0;width: 200px;background-color: #eeeeee"> 77 <a id="menu_class" class="item" href="/classes.html">班級管理</a> 78 <a id="menu_student" class="item" href="/student.html">學生管理</a> 79 <a id="menu_teacher" class="item" href="/teacher.html">老師管理</a> 80 </div> 81 <div style="position: absolute;top: 48px;left: 200px;bottom:0;right: 0;overflow: auto"> 82 83 {% block content %} {% endblock %} 84 85 </div> 86 </div> 87 <script src="/static/jquery-2.1.4.min.js"></script> 88 {% block js %} {% endblock %} 89 </body> 90 </html>
block 標籤訂義了三個能夠被子模版內容填充的block。 block 告訴模版引擎: 子模版可能會覆蓋掉模版中的這些位置。
{% block css %} {% endblock %}
{% block content %} {% endblock %}
{% block js %} {% endblock %}
{% extends "base.html" %} {% block css %} {% endblock %} {% block content %} <h1>添加班級</h1> <form action="/add_classes.html" method="POST"> <input type="text" name="caption" /> <input type="submit" value="提交"/>{{ msg }} </form> {% endblock %} {% block js %} <script> $(function () { $('#menu_class').addClass('active'); }); </script> {% endblock %}
extends 標籤是這裏的關鍵。它告訴模版引擎,這個模版「繼承」了另外一個模版。