Django templates(模板)


 為什么用templates?

views.py視圖函數是用來寫Python代碼的,HTML可以被直接硬編碼在views.py之中。如下:

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 代碼編寫和 HTML 設計是兩項不同的工作,大多數專業的網站開發環境都將他們分配給不同的人員(甚至不同部門)來完成。 設計者和HTML/CSS的編碼人員不應該被要求去編輯Python的代碼來完成他們的工作。

  • 程序員編寫 Python代碼和設計人員制作模板兩項工作同時進行的效率是最高的,遠勝於讓一個人等待另一個人完成對某個既包含 Python又包含 HTML 的文件的編輯工作。

基於這些原因,將頁面的設計和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模板組成

HTML代碼+邏輯控制代碼

你使用過一些在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 模板中遍歷復雜數據結構的關鍵是句點字符 (.)

#最好是用幾個例子來說明一下。
# 首先,句點可用於訪問列表索引,例如:

>>> 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
1993
>>> d.month
5
>>> d.day
2
>>> 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'

# 注意這里調用方法時並* 沒有* 使用圓括號 而且也無法給該方法傳遞參數;你只能調用不需參數的
# 方法。

2.2 過濾器

您可以通過使用 過濾器來改變變量的顯示。

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

過濾管道可以被* 套接* ,既是說,一個過濾器管道的輸出又可以作為下一個管道的輸入:

?
1
{{ 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 ),例如:

?
1
2
3
{% 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>
復制代碼
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 標簽是這里的關鍵。它告訴模版引擎,這個模版“繼承”了另一個模版。

 

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM