Python Web框架篇:Django templates(模板)

爲何用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)來實現這種模式。程序員

1.配置settings.py

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表達式。

只有下面列表中的標籤、過濾器和語法纔是默認就被支持的。(可是您也能夠根據須要添加您本身的擴展到模版語言中)。

2.1 變量

變量: {{ variable }}

點號(.)用來訪問變量的屬性。

當模版系統遇到點("."),它將以這樣的順序查詢:

  • 字典查詢(Dictionary lookup)
  • 屬性或方法查詢(Attribute or method lookup)
  • 數字索引查詢(Numeric index lookup)
>>> 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 # 方法。
View Code

2.2 過濾器

您能夠經過使用 過濾器來改變變量的顯示。

{{ name|lower }}。這將在變量 {{ name }} 被過濾器 lower 過濾後再顯示它的值,該過濾器將文本轉換成小寫。使用管道符號 (|)來應用過濾器。

過濾管道能夠被* 套接* ,既是說,一個過濾器管道的輸出又能夠做爲下一個管道的輸入:

{{ my_list|first|upper }} 將第一個元素並將其轉化爲大寫。

內置過濾器:

add——把add後的參數加給value

{{ value|add:"2" }}
若是 value 爲 4,則會輸出 6.
過濾器首先會強制把兩個值轉換成Int類型。若是強制轉換失敗, 它會試圖使用各類方式吧兩個值相加。它會使用一些數據類型 (字符串, 列表, 等等.) 

last 返回列表中的最後一個項目。

{{ value|last }} If value is the list ['a', 'b', 'c', 'd'], the output will be the string "d".

length 返回值的長度。

{{ 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,就替換成設置的默認值,不然就使用原本的值

 

2.3 標籤 {% tag %}

{% 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 %}

 

2.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>
View Code
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 標籤是這裏的關鍵。它告訴模版引擎,這個模版「繼承」了另外一個模版。
相關文章
相關標籤/搜索