Django---模板層(template)

在沒學習模板以前,之前的一些代碼示例須要將動態的數據傳入到網頁當中,當時傳數據比較簡單,使用字符串拼接的方來實現將數據傳入到網頁當中。
#一下代碼是先的在網頁當中嵌入當前時間
import datetime
def timer(request):
    now_time=datetime.datetime.now()
    html="<html><body>Now is :%s</body></html>" % now_time
    return HttpReponse(html)

#這樣會在網頁中嵌入數據,可是,若是數據龐大,繁多,代碼寫起來就比較亂,儘管這種技術便於解釋視圖是如何工做的,但直接將HTML硬編碼到你的視圖裏卻並非一個好的主意。
緣由:
  •     對頁面設計進行的任何改變都必須對Python代碼進行相應的修改。站點設計的修改每每比底層Python代碼的修改要繁瑣的多,所以若是能夠再也不Python代碼修改的狀況下變動設計,那將會方便的不少。
  • Python代碼的編寫和HTML設計師兩項不一樣的工做,大多數專業的網站開發環境都將他們分配給不一樣的人員(甚至不一樣的部門)來完成。設計者和HTML/CSS的編碼人員不該該被要求去編輯Python的代碼來完成他們的工做。
  • 程序員編寫Python代碼和設計人員製做模板兩項工做同時進行的效率是最高的,遠遠勝於讓一我的等待另外一我的完成對某個幾班韓Python又包含HTML的文件的編輯工做。
  • 對於這些緣由,將頁面的設計和Python的代碼分離會更乾淨簡潔和維護。咱們可使用Django的模板系統來實現這種模式。
Python的模板:HTML代碼+模板語法
模板包括在使用時會被值替換掉的變量,和控制模板邏輯的標籤。
#推薦下面寫法(方便代碼的修改)
#Python代碼
import datetime
def now_time(request):
    now=datetime.datetime.now()
    return render(request,'now_time.html',{'now_time':str(now_time)})
#html代碼(代碼寫在HTML頁面當中)
<body>
<h1>如今的時間:{{ now_time }}</h1>
</body>

模板語法:變量

    在Django中模板中遍歷複雜的數據結構的關鍵是句點字符‘.’

語法:
    
#在HTML中取值方式{{ var_name }}或者{{ var_name.索引 }}
VIEWS:
#python 代碼

def index(request):
    # 字符串 character_string
    character_string = 'hello'
    # 列表list_l
    list_l = ['old', 'boy', 'education']
    # 字典dict_d
    dict_d = {"teacher": "Teacher_wang", "student": "student_li"}
    date_time=datetime.date(2017,10,24)
    # 自定義類對象
    class Person():
        def __init__(self, name, age):
            self.name = name
            self.age = age

    person_li=Person("teacher_li",19)
    person_zhang=Person("teacher_zhang",18)
    person_wang=Person("teacher_wang",17)
    person_zhao=Person("teacher_zhao",20)

    person_list=[person_li,person_zhang,person_wang,person_zhao]


    return render(request,"index.html",
                  {"character_string":character_string,
                   "list_l":list_l,
                   "dict_d":dict_d,
                   "date_time":date_time,
                    "person_list":person_list
                   }
                  )
TEMPLATE:
<body>
<h3>字符串:{{ character_string }}</h3>
<hr>

<h3>列表第一個值:{{ list_l.0 }}</h3>
<h3>列表第二個值:{{ list_l.1 }}</h3>
<h3>列表第三個值:{{ list_l.2 }}</h3>
<hr>

<h3>字典的第一個key的值:{{ dict_d.teacher }}</h3>
<h3>字典的第二個key的值:{{ dict_d.student }}</h3>
<hr>

<h3>日期 年:{{ date_time.year }}</h3>
<h3>日期 月:{{ date_time.month }}</h3>
<h3>日期 日:{{ date_time.day }}</h3>

<hr>
<h3>自定義類對象的第一個值的姓名和年齡:{{ person_list.0.name }},{{ person_list.0.age }}</h3>
<h3>自定義類對象的第二個值的姓名和年齡:{{ person_list.1.name }},{{ person_list.1.age }}</h3>
<h3>自定義類對象的第三個值的姓名和年齡:{{ person_list.2.name }},{{ person_list.2.age }}</h3>
<h3>自定義類對象的第四個值的姓名和年齡:{{ person_list.3.name }},{{ person_list.3.age }}</h3>
</body>

#注意:句點福也能夠應用對象的方法(無參數的方法)
<h3>字典的第二個key的值:{{ dict_d.student.upper }}</h3>

模板:過濾器

語法:    
{{obj|filter__name:param}}

#練習:(template)
    {#default : 若是一個變量是空或者false,使用給定的默認值。不然使用變量的值,也能夠成爲解釋文本#}
    <h3>{{ value_null|default:"該變量爲空" }}</h3>
        
    {#lengh :返回值得長度,對字符串和列表都起做用#}
    <h3>{{ value|length }}</h3>
        
    {#將值格式化爲一個 「人類可讀的」 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)#}
    <h3>{{ value_size|filesizeformat }}</h3>
    
    {#格式化輸出時間#}
    <h3>{{ value_date|date:"Y-m-d" }}</h3>
    
    {#切片#}
    <h3>{{ value|slice:"2:-1" }}</h3>
    
    {#若是字符串字符多於指定的字符數量,那麼會被截斷。截斷的字符串將以可翻譯的省略號序列(「...」)結尾。參數:要截斷的字符數#}
    <h3>{{ value|truncatechars:30 }}</h3>

        
        
    #views:
    def index(request):
        value_null=''
        value="The purpose of life is to live it, to taste experience to the utmost, to  reach out eagerly and without fear for newer and richer experience."
        value_size='0726'
        value_date=datetime.datetime.now()
        return render(request,'index.html',
                  {"value_null":value_null,
                   "value":value,
                   "value_size":value_size,
                   "value_date":value_date})

模板:標籤

    標籤看起來像是這樣的:{% tag %}。標籤比變量更加複雜:一些在輸出文本中建立文本,一些經過循環或者邏輯來控制流程,一些加載其後的變量將使用到的額外信息到模板中。
    一些標籤須要開始和結束標籤(例如{% tag %}....標籤內容...{% endtag %})。
#for標籤
#遍歷每個元素:
{% for person in person_list %}
    <h1>姓名:{{ person.name }}年齡:{{ person.age }}</h1>
{% endfor %}

#views代碼:
    class Person():
        def __init__(self, name, age):
            self.name = name
            self.age = age

    person_li=Person("teacher_li",19)
    person_zhang=Person("teacher_zhang",18)
    person_wang=Person("teacher_wang",17)
    person_zhao=Person("teacher_zhao",20)
    person_list=[person_li,person_zhang,person_wang,person_zhao]

    return render(request,'index.html',{"person_list":person_list})


#也能夠反向循環 在for循環結尾加上reversed({% for person in person_list reversed %})
#注:循環序號能夠經過{{forloop}}顯示  
{% for key,val in dict_d.items  %}
    <h1>{{ forloop.counter  }}key:{{ key }} val:{{ val }}</h1>
{% endfor %}
for...empty
#for 標籤帶有一個可選的{% empty %} 從句,以便在給出的組是空的或者沒有被找到時,能夠有所操做。
{% for key,val in dict_d.items %}
    <p>{{ key }}</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 %}

自定義過濾器

     1.在setting中的INSTALLED_APPS配置當前的app否則Django沒法找到自定義的sipple_tag(有的版本會自動添加沒有自動添加的手動添加就行。)
    2.在app中建立templatetags模塊(該模塊名只能是 templatetags
    3.建立.py文件,如:my_tag.py
#1.建立完.py文件以後第一件事就是先導入wenjian
from django import template
from django.utils.safestring import mark_safe
 
register = template.Library()   #register的名字是固定的,不可改變
#2.其次開始寫代碼(相似裝飾器的東西必須加)
@register.filter

def multi(v1,v2):
    return  v1 * v2
#3.在使用自定義simple_tag和filter的html文件中導入以前建立的 my_tags.py
#導入方法
{% load mytag %}
#4.調用方式
<h1>{{ i|multi:6 }}</h1>#(i的值是666)
自定義標籤
#導入的方法跟上面同樣,調用的時候有點不同。
#1.先建立標籤

@register.simple_tag
def multiTag(x,y):
    return x*y

#2.調用muliTag
<h1>{% multiTag 33 66 %}</h1>
             
    對比過濾器與自定義標籤的使用:
       過濾器函數的參數只能有兩個,自定義標籤無參數限制
       過濾器能夠與邏輯標籤共同使用,好比if標籤。自定義標籤不能夠。

模板:繼承

  •     首先先要引入靜態文件:

#1.配置靜態文件的路徑,在settings.py文件中添加以下代碼:
    STATICFILES_DIRS=[
    os.path.join(BASE_DIR,"static")
]
#2.建立名稱爲static的文件,而後在其目錄下添加靜態文件如bootstrap,jquery等文件
#3.在html文件中引入文件
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/jquery-3.2.1.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>

  • 模板繼承

#Django模版引擎中最強大也是最複雜的部分就是模版繼承了。模版繼承可讓您建立一個基本的「骨架」模版,它包含您站點中的所有元素,而且能夠定義可以被子模版覆蓋的 blocks 。

#示例代碼:
    #母版中的代碼
    <!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="UTF-8">
    <title>{% block title %}Title{% endblock %}</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/jquery-3.2.1.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <style>
        .body_top{
            width: 100%;
            height: 50px;
            background-color: #000000;
        }
        .body_menu{
            width:25%;
            height: 450px;
            background-color: #cccccc;
            float: left;
        }
        .body_right{
            width:75%;
            height: 450px;
            float: left;
        }
        .body_bottom{
             width: 100%;
            height: 50px;
            background-color: #0f0f0f;
        }
    </style>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="body_top"></div>
    </div>
    <div class="row">
        <div class="body_menu">
            {% block menu %}
                <ul>
                    <li><a href="/student_info/1">班級一</a></li>
                    <li><a href="/student_info/2">班級二</a></li>
                    <li><a href="/student_info/3">班級三</a></li>
                </ul>
            {% endblock %}
        </div>
        <div class="body_right">
            {% block right %}

            {% endblock %}
        </div>
    </div>
    <div class="row">
        <div class="body_bottom"></div>
    </div>
</div>




<button class="btn btn-success">添加</button>
</body>
</html>


#這個模版,咱們把它叫做 base.html, 它定義了一個能夠用於兩列排版頁面的簡單HTML骨架。「子模版」的工做是用它們的內容填充空的blocks。
#在這個例子中, block 標籤訂義了三個能夠被子模版內容填充的block。 block 告訴模版引擎: 子模版可能會覆蓋掉模版中的這些位置。
#子模版可能看起來是這樣的:
{% extends "base.html" %}
{% block menu %}
<ul>
    <li><a href="">學生信息一</a></li>
    <li><a href="">學生信息二</a></li>
    <li><a href="">學生信息三</a></li>
</ul>
{% endblock %}
{% block right %}
    <h1>班級信息</h1>
    <h3>{{ classId }}班</h3>
{% endblock %}
#extends 標籤是這裏的關鍵。它告訴模版引擎,這個模版「繼承」了另外一個模版。當模版系統處理這個模版時,首先,它將定位父模版——在此例中,就是「base.html」。
#
#那時,模版引擎將注意到 base.html 中的三個 block 標籤,並用子模版中的內容來替換這些block。根據 blog_entries 的值,輸出可能看起來是這樣的:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/jquery-3.2.1.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <style>
        .body_top{
            width: 100%;
            height: 50px;
            background-color: #000000;
        }
        .body_menu{
            width:25%;
            height: 450px;
            background-color: #cccccc;
            float: left;
        }
        .body_right{
            width:75%;
            height: 450px;
            float: left;
        }
        .body_bottom{
             width: 100%;
            height: 50px;
            background-color: #0f0f0f;
        }
    </style>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="body_top"></div>
    </div>
    <div class="row">
        <div class="body_menu">
                <ul>
    <li><a href="">學生信息一</a></li>
    <li><a href="">學生信息二</a></li>
    <li><a href="">學生信息三</a></li>
</ul>
        </div>
        <div class="body_right">
            
    <h1>班級信息</h1>
    <h3>{{ classId }}班</h3>
        </div>
    </div>
    <div class="row">
        <div class="body_bottom"></div>
    </div>
</div>

<button class="btn btn-success">添加</button>
</body>
</html>
#請注意,子模版並無定義 sidebar block,因此係統使用了父模版中的值。父模版的 {% block %} 標籤中的內容老是被用做備選內容(fallback)。


#####這種方式使代碼獲得大程度的服用而且使得添加內容到共享的內容區域更加簡單,例如,部分範圍內的導航。
#裏是使用繼承的一些提示:

#1.若是你在模版中使用 {% extends %} 標籤,它必須是模版中的第一個標籤。其餘的任何狀況下,模版繼承都將沒法工做。
#在base模版中設置越多的 {% block %} 標籤越好。請記住,子模版沒必要定義所有父模版中的blocks,因此,你能夠在大多數blocks中填充合理的默認內容,而後,只定義你須要的那一個。多一點鉤子總比少一點好。
#3.若是你發現你本身在大量的模版中複製內容,那可能意味着你應該把內容移動到父模版中的一個 {% block %} 中。
#4.爲了更好的可讀性,你也能夠給你的 {% endblock %} 標籤一個 名字 例如:
    {% block content %}
    ...
    {% endblock content %} 
#5.最後,請注意您並不能在一個模版中定義多個相同名字的 block 標籤。這個限制的存在是由於block標籤的做用是「雙向」的。這個意思是,block標籤不只提供了一個坑去填,它還在 _父模版_中定義了填坑的內容。若是在一個模版中有兩個名字同樣的 block 標籤,模版的父模版將不知道使用哪一個block的內容。
STUDY HARD AND MAKE PROGRESSEVERY DAY



相關文章
相關標籤/搜索