Django的模板層

  在前面的學習中注意到在例子視圖中返回文本的方式有點特別。 也就是說,HTML被直接硬編碼在 Python代碼之中。css

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

  儘管上面這種方法便於解釋視圖是如何工做的,但直接將HTML硬編碼到視圖裏卻並非一個好主意。html

    對頁面設計進行的任何改變都必須對 Python 代碼進行相應的修改。 站點設計的修改每每比底層 Python 代碼的修改要頻繁得多,所以若是能夠在不進行 Python 代碼修改的狀況下變動設計,那將會方便得多。

    Python 代碼編寫和 HTML 設計是兩項不一樣的工做,大多數專業的網站開發環境都將他們分配給不一樣的人員(甚至不一樣部門)來完成。 設計者和HTML/CSS的編碼人員不該該被要求去編輯Python的代碼來完成他們的工做。

    程序員編寫 Python代碼和設計人員製做模板兩項工做同時進行的效率是最高的,遠勝於讓一我的等待另外一我的完成對某個既包含 Python又包含 HTML 的文件的編輯工做。
上面這種HTML硬編碼在python中的劣勢

  基於上面這些緣由,將頁面的設計和Python的代碼分離開會更乾淨簡潔更容易維護。 咱們可使用 Django的 模板系統 (Template System)來實現這種模式。java

  python的模板:HTML代碼+模板語法python

  模型包括在使用時會被值替換掉的 變量,和控制模版邏輯的 標籤linux

  三種寫法:程序員

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、模板語法之變量

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

  語法:django

{{var_name}}

一、定義變量傳入模板

/templates_demo/app01/views.py:bootstrap

from django.shortcuts import render
# Create your views here.

def index(request):
    """
    模板語法只有兩個:
    變量:{{}}
        一、深度查詢   句點符
        二、過濾器
    標籤:{% %}
    :param request:
    :return:
    """
    name = "yuan"  # 定義變量
    i = 10
    l = [111,222,333]
    info = {"name":"yuan","age":22}

    b = True

    class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age

    alex = Person("alex", 333)
    egon = Person("egon", 222)

    person_list = [alex, egon]

    # return render(request,"index.html", {'name': name})  # 注意模板文件和html文件的區別:含不含模板語法
    return render(request, "index.html",locals())   # 局部變量直接傳入模板,變量名一一對應

二、深度查詢

  {{}}嵌套視圖傳進去的變量,若是是序列數據類型或對象能夠經過「.」把響應的值取出來。數組

/templates_demo/templates/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>index</h1>
    <p>{{ name }}</p>
    <p>{{ i }}</p>
    <p>{{ info }}</p>
    <p>{{ l }}</p>
    <p>{{ alex }}</p>
    <p>{{ person_list }}</p>
    <p>{{ b }}</p>

    <hr>
    深度查詢

    <p>{{ l.1 }}</p>
    <p>{{ info.name }}</p>
    <p>{{ alex.age }}</p> <!--拿到對象的屬性-->
    <p>{{ person_list.1.age }}</p>   <!--拿到列表中第二個對象的age屬性-->
</body>
</html> 

運行結果:

  

  注意:句點符也能夠用來引用對象的方法(無參數方法):

<h4>字典:{{ dic.name.upper }}</h4>

三、模板語法之過濾器

  功能:把視圖傳進來的變量加以修飾後再顯示

  語法:

{{obj|filter__name:param}}

(1)default

  若是一個變量是false或者爲空,使用給定的默認值。不然,使用變量的值。例如:

{{ value|default:"nothing" }}

(2)length

  返回值的長度。它對字符串和列表都起做用。例如:

{{ value|default:"nothing" }}

  若是value是['a','b','c','d'],那麼輸出是4。

(3)filesizeformat

  將值格式化爲一個 「人類可讀的」 文件尺寸 (例如 '13 KB''4.1 MB''102 bytes', 等等)。例如:

{{ value|filesizeformat }}

  若是 value 是 1234345,輸出將會是 1.2 MB。  

(4)date

  若是 value=datetime.datetime.now()

{{ value|date:"Y-m-d" }}  

(5)slice

  若是 value="hello world",以下會輸出:llo worl

{{ value|slice:"2:-1" }}

(6)truncatechars

  若是字符串字符多於指定的字符數量,那麼會被截斷截斷的字符串將以可翻譯的省略號序列(「...」)結尾。

  參數:要截斷的字符數

  例如:

{{ value|truncatechars:9 }}

  若是value是"Joel  是  a  >",輸出將會是:"Joel  i  ..."。

(7)safe

  Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統,後臺添加的文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本,若是自動轉義的話顯示的就是保護HTML標籤的源文件。爲了在Django中關閉HTML的自動轉義有兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的沒必要轉義。

link = '<a href=">click</a>'

  直接在模板中使用link:

<p>{{ link }}</p>

在頁面中,Django默認作了轉義,&lt;a href=&quot;&gt;click&lt;/a&gt;

  所以必須添加safe過濾器:

<p>{{ link|safe }}</p>

代碼示例:

from django.shortcuts import render

# Create your views here.


def index(request):
    """
    模板語法只有兩個:
    變量:{{}}
        一、深度查詢   句點符
        二、過濾器
    標籤:{% %}
    :param request:
    :return:
    """
    name = "yuan"  # 定義變量
    i = 10
    l = [111,222,333]
    info = {"name":"yuan","age":22}

    b = True

    class Person(object):

        def __init__(self, name, age):
            self.name = name
            self.age = age

    alex = Person("alex", 333)
    egon = Person("egon", 222)

    person_list = [alex, egon]

    people_list = []

    #######################
    import datetime

    now = datetime.datetime.now()

    file_size= 1234345

    value = "hello world"
    text = "hello python hi luffycity go java linux"

    link = '<a href=">click</a>'


    # return render(request,"index.html", {'name': name})  # 注意模板文件和html文件的區別:含不含模板語法

    return render(request, "index.html",locals())   # 局部變量直接傳入模板,變量名一一對應
/templates_demo/app01/views.py

 /templates_demo/templates/index.html:

<h3>過濾器</h3>
<p>{{ now }}</p>
<p>{{ now|date:"Y-m-d" }}</p>
<p>{{ people_list|default:"數據爲空" }}</p>
<p>{{ person_list|length }}</p>
<p>{{ file_size|filesizeformat }}</p>
<p>{{ value|slice:"2:-1" }}</p>
<p>{{ text|truncatechars:9 }}</p>
<p>{{ link }}</p>
<p>{{ link|safe }}</p>

  在頁面中展現效果:

    

這裏簡單介紹一些經常使用的模板的過濾器,更多詳見

2、模板語法之標籤

  標籤看起來像是這樣的: {% tag %}。標籤比變量更加複雜:一些在輸出中建立文本,一些經過循環或邏輯來控制流程,一些加載其後的變量將使用到的額外信息到模版中。

  一些標籤須要開始和結束標籤 (例如{% tag %} ...標籤 內容 ... {% endtag %})。

一、for標籤

(1)遍歷每個元素:

{% for i in l %}
    <p>{{  i }}</p>
{% endfor %}

  利用{% for obj in list reversed %}反向完成循環

{% for i in l reversed %}
    <p>{{  i }}</p>
{% endfor %}

(2)遍歷一個字典:views.py中有:info = {"name":"yuan","age":22}

{% for i in info %}
    <p>{{ i }}</p>
{% endfor %}

  頁面顯示:name:yuan     age:22

(3)遍歷對象數組

{% for person in person_list %}
    <p>{{ person.name }}  {{ person.age }}</p>
{% endfor %}

{# forloop.counter 序號,默認從1開始計數  counter0的序號,從0開始計數 #}
{% for person in person_list %}
    <p>{{ forloop.counter0 }} {{ person.name }}  {{ person.age }}</p>
{% endfor %}

  頁面顯示:alex 333       egon 222

         0 alex 333       1 egon 222

注:循環序號能夠經過{{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 標籤帶有一個可選的{% empty %} 從句,以便在給出的組是空的或者沒有被找到時,能夠有所操做。

  如:在view.py中建立:empty_list = []

{% for n in empty_list%}
    <p>{{ forloop.counter0 }} {{ n.name }}  {{ n.age }}</p>
    {% empty %}
    <p>列表爲空</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 %}

  示例:

{% if user %}
    <p>
        <a href="">hi {{ user }}</a>
        <a href="">註銷</a>
    </p>
{% else %}
    <p>
        <a href="">登陸</a>
        <a href="">註冊</a>
    </p>
{% endif %}

  當user = None,頁面顯示:登陸 註冊

  當user = alex,頁面顯示:hi alex 註銷

四、with標籤

  使用一個簡單的名字緩存一個複雜的變量,當你須要使用一個「昂貴的」方法(好比訪問數據庫)不少次的時候是很是有用的。(替換名字)

{{ person_list.1.name }}
{% with person_list.1.name as p_l %}
    {{ p_l }}
{% endwith %}

  例如上例這種,因爲深度查詢很是長,用一個簡單的名字替換。   

五、csrf_token

  這個標籤用於跨站請求僞造保護。{% csrf_token %}能夠渲染出一個input標籤。點擊提交時,會提交給服務器驗證經過校驗。以下圖所示:

  

(1)代碼示例:

  urls.py:

from django.contrib import admin
from django.urls import path, re_path

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),    # 含正則的時候須要使用re_path
    path('login/', views.login)
]

  app01/views.py:

from django.shortcuts import render,HttpResponse
# Create your views here.

def login(request):
    if request.method == "POST":
        return HttpResponse("OK")
    return render(request, "login.html")

  login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}
    <input type="text" name="user">
    <input type="submit">
</form>
</body>
</html>

(2)在瀏覽器運行效果以下

  1)沒有添加csrf_token時,輸入信息點擊提交

  

  2)添加了csrf_token後:

  

3、自定義標籤和過濾器

一、在settings中的INSTALLED_APPS配置當前app

  否則django沒法找到自定義的simple_tag

  

二、在app中建立templatetags模塊

  注意:模塊名只能是templatetags

  

  Django去找自定義標籤的時候,就固定會在註冊的app中尋找templatetags的package.

三、在templatetags中建立任意 .py 文件

  如建立:my_tags_filter.py

from django import template

register = template.Library()   # register不能變

@register.filter
def multi_filter(x,y):
    # 新過濾器,實現相乘
    return x*y

@register.simple_tag
def multi_tag(x,y):
    # 新標籤
    return x**y

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

from django.utils.safestring import mark_safe

@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_tags_filter.py 

{% load my_tags_filter %}

五、使用simple_tag和filter(如何調用)

<h4>自定義過濾器</h4>
{% load my_tags_filter %}
<p>{{ i|multi_filter:20 }}</p>

<h4>自定義標籤</h4>
<p>{% multi_tag 4 2 %}</p>
<p>{% multi_tag_higher 3 2 4 %}</p>

{#  過濾器最多隻能傳兩個形參;自定義標籤沒有數量限制  #}
{#  標籤不能進行邏輯判斷  #}
{% if i|multi_filter:10 > 50 %}
    <p>1010</p>
{% else %}
    <p>{{ i }}</p>
{% endif %}

   注意:過濾器({{  }})能夠用再if等語句後,標籤({%  %})不能夠進行邏輯判斷

{% if num|filter_multi:30 > 100 %}
    {{ num|filter_multi:30 }}
{% endif %}

六、simple_tag 和 filter 的區別

  • simple_tag:能夠有多個參數,通常是作數據處理,但不能作if判斷語句
  • filter:通常只能有1個參數(能夠字符串切割,變通爲多個參數),過濾器,通常是return true或者false,能夠和if判斷語句使用.在過濾器 {{ var|foo:"bar" }} 中 ,過濾器 foo 會被傳入變量 var 和默認參數 bar。過濾器函數應該總有返回值

4、模板繼承(extend)標籤

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

  仍是用templates_demo這個項目爲例來理解模板繼承:

一、include 模板標籤  {% include %}

  利用模板加載機制的內建模板標籤: {% include %} 。該標籤容許在(模板中)包含其它的模板的內容。 標籤的參數是所要包含的模板名稱,能夠是一個變量,也能夠是用單/雙引號硬編碼的字符串。 每當在多個模板中出現相同的代碼時,就應該考慮是否要使用 {% include %} 來減小重複。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 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">
        * {
            margin: 0;
            padding: 0;
        }
        .header{
            width: 100%;
            height: 50px;
            background-color: #369;
        }
    </style>
</head>
<body>
    <div class="header"></div>

    <div class="container">
        <div class="row">
            <div class="col-md-3">
                {% include 'advertise.html' %}
            </div>
            <div class="col-md-9">
                <h1>index</h1>
                <p>{{ name }}</p>
                <p>{{ i }}</p>
                <p>{{ info }}</p>
                <p>{{ l }}</p>
                <p>{{ alex }}</p>
                <p>{{ person_list }}</p>
                <p>{{ b }}</p>

                <hr>深度查詢
                <p>{{ l.1 }}</p>
                <p>{{ info.name }}</p>
                <p>{{ alex.age }}</p> <!--拿到對象的屬性-->
                <p>{{ person_list.1.age }}</p>   <!--拿到列表中第二個對象的age屬性-->

                <h3>過濾器</h3>
                <p>{{ now }}</p>
                <p>{{ now|date:"Y-m-d" }}</p>
                <p>{{ people_list|default:"數據爲空" }}</p>
                <p>{{ person_list|length }}</p>
                <p>{{ file_size|filesizeformat }}</p>
                <p>{{ value|slice:"2:-1" }}</p>
                <p>{{ text|truncatechars:9 }}</p>
                <p>{{ link }}</p>
                <p>{{ link|safe }}</p>

                <h4>for標籤</h4>
                {% for i in l reversed %}
                    <p>{{  i }}</p>
                {% endfor %}
                {% for i, j in info.items %}
                    <p>{{ i }}:{{ j }}</p>
                {% endfor %}
                {% for person in person_list %}
                    <p>{{ person.name }}  {{ person.age }}</p>
                {% endfor %}

                {# forloop.counter 序號,默認從1開始計數  counter0的序號,從0開始計數 #}
                {% for person in person_list %}
                    <p>{{ forloop.counter0 }} {{ person.name }}  {{ person.age }}</p>
                {% endfor %}

                {% for n in empty_list%}
                    <p>{{ forloop.counter0 }} {{ n.name }}  {{ n.age }}</p>
                    {% empty %}
                    <p>列表爲空</p>
                {% endfor %}

                <hr>
                {% if user %}
                    <p>
                        <a href="">hi {{ user }}</a>
                        <a href="">註銷</a>
                    </p>
                {% else %}
                    <p>
                        <a href="">登陸</a>
                        <a href="">註冊</a>
                    </p>
                {% endif %}

                <hr>
                {{ person_list.1.name }}
                {% with person_list.1.name as p_l %}
                    {{ p_l }}
                {% endwith %}
                <hr>

                <h4>自定義過濾器</h4>
                {% load my_tags_filter %}
                <p>{{ i|multi_filter:20 }}</p>

                <h4>自定義標籤</h4>
                <p>{% multi_tag 4 2 %}</p>
                <p>{% multi_tag_higher 3 2 4 %}</p>

                {#  過濾器最多隻能傳兩個形參;自定義標籤沒有數量限制  #}
                {#  標籤不能進行邏輯判斷  #}
                {% if i|multi_filter:10 > 50 %}
                    <p>1010</p>
                {% else %}
                    <p>{{ i }}</p>
                {% endif %}
            </div>
        </div>
    </div>
</body>
</html>
/templates_demo/templates/index.html

  利用模板裏的{% include 'advertise.html' %} 引入advertise.html

<div class="action">
    <div class="panel panel-danger">
        <div class="panel-heading">Panel heading without title</div>
        <div class="panel-body">
            Panel content  111
        </div>
    </div>
    <div class="panel panel-warning">
        <div class="panel-heading">Panel heading without title</div>
        <div class="panel-body">
            Panel content  222
        </div>
    </div>
    <div class="panel panel-success">
        <div class="panel-heading">Panel heading without title</div>
        <div class="panel-body">
            Panel content  333
        </div>
    </div>
</div>
/templates_demo/templates/advertise.html

  運行後瀏覽器效果以下所示:

  

二、模板繼承{% extends 'base.html' %}

(1)/templates/base.html:

  通常都是用base.html定義了一個能夠用於兩列排版頁面的簡單HTML骨架

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 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">
        * {
            margin: 0;
            padding: 0;
        }
        .header{
            width: 100%;
            height: 50px;
            background-color: #369;
        }
    </style>
</head>
<body>
    <div class="header"></div>

    <div class="container">
        <div class="row">
            <div class="col-md-3">
                {% include 'advertise.html' %}
            </div>
            <div class="col-md-9">
                {% block con %}

                {% endblock %}
            </div>
        </div>
    </div>
</body>
</html>

(2)子模板/templates/index.html

  「子模版」的工做是用它們的內容填充空的blocksblock 告訴模版引擎: 子模版可能會覆蓋掉模版中的這些位置。

{% extends 'base.html' %}


{% block con %}
    <h1>index</h1>
    <p>{{ name }}</p>
    <p>{{ i }}</p>
    <p>{{ info }}</p>
    <p>{{ l }}</p>
    <p>{{ alex }}</p>
    <p>{{ person_list }}</p>
    <p>{{ b }}</p>

    <hr>深度查詢
    <p>{{ l.1 }}</p>
    <p>{{ info.name }}</p>
    <p>{{ alex.age }}</p> <!--拿到對象的屬性-->
    <p>{{ person_list.1.age }}</p>   <!--拿到列表中第二個對象的age屬性-->

    <h3>過濾器</h3>
    <p>{{ now }}</p>
    <p>{{ now|date:"Y-m-d" }}</p>
    <p>{{ people_list|default:"數據爲空" }}</p>
    <p>{{ person_list|length }}</p>
    <p>{{ file_size|filesizeformat }}</p>
    <p>{{ value|slice:"2:-1" }}</p>
    <p>{{ text|truncatechars:9 }}</p>
    <p>{{ link }}</p>
    <p>{{ link|safe }}</p>

    <h4>for標籤</h4>
    {% for i in l reversed %}
        <p>{{  i }}</p>
    {% endfor %}
    {% for i, j in info.items %}
        <p>{{ i }}:{{ j }}</p>
    {% endfor %}
    {% for person in person_list %}
        <p>{{ person.name }}  {{ person.age }}</p>
    {% endfor %}

    {# forloop.counter 序號,默認從1開始計數  counter0的序號,從0開始計數 #}
    {% for person in person_list %}
        <p>{{ forloop.counter0 }} {{ person.name }}  {{ person.age }}</p>
    {% endfor %}

    {% for n in empty_list%}
        <p>{{ forloop.counter0 }} {{ n.name }}  {{ n.age }}</p>
        {% empty %}
        <p>列表爲空</p>
    {% endfor %}

    <hr>
    {% if user %}
        <p>
            <a href="">hi {{ user }}</a>
            <a href="">註銷</a>
        </p>
    {% else %}
        <p>
            <a href="">登陸</a>
            <a href="">註冊</a>
        </p>
    {% endif %}

    <hr>
    {{ person_list.1.name }}
    {% with person_list.1.name as p_l %}
        {{ p_l }}
    {% endwith %}
    <hr>

    <h4>自定義過濾器</h4>
    {% load my_tags_filter %}
    <p>{{ i|multi_filter:20 }}</p>

    <h4>自定義標籤</h4>
    <p>{% multi_tag 4 2 %}</p>
    <p>{% multi_tag_higher 3 2 4 %}</p>

    {#  過濾器最多隻能傳兩個形參;自定義標籤沒有數量限制  #}
    {#  標籤不能進行邏輯判斷  #}
    {% if i|multi_filter:10 > 50 %}
        <p>1010</p>
    {% else %}
        <p>{{ i }}</p>
    {% endif %}
{% endblock %}
/templates/index.html

  extends 標籤是這裏的關鍵。它告訴模版引擎,這個模版「繼承」了另外一個模版。當模版系統處理這個模版時,首先,它將定位父模版——在此例中,就是「base.html」

  模版引擎將注意到 base.html 中的 block 標籤,並用子模版中的內容來替換這些block。再次訪問頁面:

  

  同時若是想定製一個和父模板基本相同的頁面如order.html:

{% extends 'base.html' %}


{% block con %}
    <h3>訂單</h3>
{% endblock %}

  顯示效果以下:

  

(3)在base.html中定義多個block

  在base.html中能夠定義多個block方便繼承的頁面擴寫內容,解決http頁面代碼複用性的問題。好比把titile標籤改成block:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% block 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">
        * {
            margin: 0;
            padding: 0;
        }
        .header{
            width: 100%;
            height: 50px;
            background-color: #369;
        }
    </style>
</head>
<body>
    <div class="header"></div>

    <div class="container">
        <div class="row">
            <div class="col-md-3">
                {% include 'advertise.html' %}
            </div>
            <div class="col-md-9">
                {% block con %}

                {% endblock %}
            </div>
        </div>
    </div>
</body>
</html>
base.html
{% extends 'base.html' %}

{% block title %}
    <titile>orders</titile>
{% endblock %}


{% block con %}
    <h3>訂單</h3>
{% endblock %}

  請注意,子模版並無定義 sidebar block,因此係統使用了父模版中的值。父模版的 {% block %} 標籤中的內容老是被用做備選內容(fallback)。

  這種方式使代碼獲得最大程度的複用,而且使得添加內容到共享的內容區域更加簡單,例如,部分範圍內的導航。

(4)這裏是使用繼承的一些提示

  1)若是你在模版中使用 {% extends %} 標籤,它必須是模版中的第一個標籤。其餘的任何狀況下,模版繼承都將沒法工做。(將{% extends 'base.html' %}寫在首行)

  2)在base模版中設置越多的 {% block %} 標籤越好。請記住,子模版沒必要定義所有父模版中的blocks,因此,你能夠在大多數blocks中填充合理的默認內容,而後,只定義你須要的那一個。多一點鉤子總比少一點好。 

  3)若是你發如今模版中有大量的複製內容,那可能意味着你應該把內容移動到父模版中的一個 {% block %} 中。

  4)若是須要從父模板中獲取block中的內容,可使用{{ block.super }}拿到父模板的內容,並繼續續寫。

{% extends 'base.html' %}

{% block title %}
    <titile>orders</titile>
{% endblock %}

{% block con %}
    {{ block.super }}
    <h3>訂單</h3>
{% endblock %}

  base.html:

<div class="col-md-9">
    {% block con %}
        <h4>content</h4>
    {% endblock %}
</div>    

  訪問網頁效果以下:

  

  5)爲了更好的可讀性,你也能夠給你的 {% endblock %} 標籤一個 名字 。例如:

{% block content %}
...
{% endblock content %}  

  在大型模版中,這個方法幫你清楚的看到哪個  {% block %} 標籤被關閉了。

  6)不能在一個模版中定義多個相同名字的 block 標籤。

三、總結extend和include

  include有功能extend都有,但extend擴展盒子的功能include不具有。所以extend功能更增強大,推薦在模板複用的時候使用繼承關係。

相關文章
相關標籤/搜索