Python之路【第二十八篇】:django視圖層、模塊層

 一、視圖函數

文件在view_democss

  一個視圖函數簡稱視圖,是一個簡單的Python 函數,它接受Web請求而且返回Web響應。響應能夠是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片. . . 是任何東西均可以。不管視圖自己包含什麼邏輯,都要返回響應。代碼寫在哪裏也無所謂,只要它在你的Python目錄下面。除此以外沒有更多的要求了——能夠說「沒有什麼神奇的地方」。爲了將代碼放在某處,約定是將視圖放置在項目或應用程序目錄中的名爲views.py的文件中。html

視圖層,熟練掌握兩個對象便可:請求對象(request)和響應對象(HttpResponse)java

視圖層之請求對象python

http://127.0.0.1:8000/index/?name=simon&age=18
url:協議://IP:port//路徑?get請求數據

 1.1請求對象

屬性linux

view_demo/urlsajax

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

from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r"index/", views.index), #index(request)
    re_path(r"^$", views.index)  #跟上邊對應的視圖函數同樣,能夠直接ip+端口訪問,不需路徑;這樣匹配到的路徑爲跟路徑
]

 

 

views數據庫

from django.shortcuts import render

# Create your views here.

from django.shortcuts import HttpResponse
def index(request):
    print("method", request.method) #告訴你這是次GET請求;index提交form表單就變成post請求了
    print(request.GET)
    #print(request.GET("name"))
    print(request.POST)

    print(request.path)  #只能拿到路徑
    print(request.get_full_path()) #既能夠拿到數據,又能夠拿到路徑

    return render(request, "index.html")

indexdjango

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>              #不加下面着重顏色的這個它仍是get請求
    <form action="" method="post">  {#action裏邊能夠加http://127.0.0.1:8000/index/也能夠加index/都是默認會生成,若是都不寫它會當前form表單所在的url拿到#}
        姓名<input type="text" name="name">
        年齡<input type="text" name="age">
        <input type="submit">
    </form>
</body>
</html>
    http://127.0.0.1  :8000/index/?name=simon&age=27
url 協議(即http)://IP:port/路徑?get請求數據(參數) ;端口號和?前面的就是路徑,後邊的name=simon&age=27是參數請求數據   

 

method GET  
<QueryDict: {'a': ['1']}>  #get取到的數據
<QueryDict: {}>            #post取到的數據
/index/     
/index/?a=1  #路徑
[26/May/2018 15:16:08] "GET /index/?a=1 HTTP/1.1" 200 292
[12/Aug/2018 18:56:46] "GET /index//?name=simon&age=27 HTTP/1.1" 200 320
method GET
<QueryDict: {'name': ['simon'], 'age': ['27']}>
<QueryDict: {}>
/index/
/index/?name=simon&age=27
[12/Aug/2018 18:57:18] "GET /index/?name=simon&age=27 HTTP/1.1" 200 320
method POST  #提交form表單的時候,可是路徑沒有變化
<QueryDict: {'name': ['simon'], 'age': ['27']}> #GET
<QueryDict: {'name': ['alex'], 'age': ['18']}> #POST
/index/                  #拿到路徑path 
/index/?name=simon&age=27  #既能夠打印路徑也能夠打印數據 get_full_path()
[12/Aug/2018 18:57:46] "POST /index/?name=simon&age=27 HTTP/1.1" 200 320

request的屬性

django將請求報文中的請求行、首部信息、內容主體封裝成 HttpRequest 類中的屬性。 除了特殊說明的以外,其餘均爲只讀的。bootstrap

/*

1.HttpRequest.GET

  一個相似於字典的對象,包含 HTTP GET 的全部參數。詳情請參考 QueryDict 對象。

2.HttpRequest.POST

  一個相似於字典的對象,若是請求中包含表單數據,則將這些數據封裝成 QueryDict 對象。

  POST 請求能夠帶有空的 POST 字典 —— 若是經過 HTTP POST 方法發送一個表單,可是表單中沒有任何的數據,QueryDict 對象依然會被建立。
   所以,不該該使用 if request.POST  來檢查使用的是不是POST 方法;應該使用 if request.method == "POST"
  另外:若是使用 POST 上傳文件的話,文件信息將包含在 FILES 屬性中。
   
   注意:鍵值對的值是多個的時候,好比checkbox類型的input標籤,select標籤,須要用:
        request.POST.getlist("hobby")

3.HttpRequest.body

  一個字符串,表明請求報文的主體。在處理非 HTTP 形式的報文時很是有用,例如:二進制圖片、XML,Json等。
  可是,若是要處理表單數據的時候,推薦仍是使用 HttpRequest.POST 。


4.HttpRequest.path

  一個字符串,表示請求的路徑組件(不含域名)。
  例如:"/music/bands/the_beatles/"

5.HttpRequest.method

  一個字符串,表示請求使用的HTTP 方法。必須使用大寫。
  例如:"GET"、"POST"


6.HttpRequest.encoding

  一個字符串,表示提交的數據的編碼方式(若是爲 None 則表示使用 DEFAULT_CHARSET 的設置,默認爲 'utf-8')。
   這個屬性是可寫的,你能夠修改它來修改訪問表單數據使用的編碼。
   接下來對屬性的任何訪問(例如從 GET 或 POST 中讀取數據)將使用新的 encoding 值。
   若是你知道表單數據的編碼不是 DEFAULT_CHARSET ,則使用它。


7.HttpRequest.META

   一個標準的Python 字典,包含全部的HTTP 首部。具體的頭部信息取決於客戶端和服務器,下面是一些示例:

    CONTENT_LENGTH —— 請求的正文的長度(是一個字符串)。
    CONTENT_TYPE —— 請求的正文的MIME 類型。
    HTTP_ACCEPT —— 響應可接收的Content-Type。
    HTTP_ACCEPT_ENCODING —— 響應可接收的編碼。
    HTTP_ACCEPT_LANGUAGE —— 響應可接收的語言。
    HTTP_HOST —— 客服端發送的HTTP Host 頭部。
    HTTP_REFERER —— Referring 頁面。
    HTTP_USER_AGENT —— 客戶端的user-agent 字符串。
    QUERY_STRING —— 單個字符串形式的查詢字符串(未解析過的形式)。
    REMOTE_ADDR —— 客戶端的IP 地址。
    REMOTE_HOST —— 客戶端的主機名。
    REMOTE_USER —— 服務器認證後的用戶。
    REQUEST_METHOD —— 一個字符串,例如"GET" 或"POST"。
    SERVER_NAME —— 服務器的主機名。
    SERVER_PORT —— 服務器的端口(是一個字符串)。
   從上面能夠看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 以外,請求中的任何 HTTP 首部轉換爲 META 的鍵時,
    都會將全部字母大寫並將鏈接符替換爲下劃線最後加上 HTTP_  前綴。
    因此,一個叫作 X-Bender 的頭部將轉換成 META 中的 HTTP_X_BENDER 鍵。

8.HttpRequest.FILES

  一個相似於字典的對象,包含全部的上傳文件信息。
   FILES 中的每一個鍵爲<input type="file" name="" /> 中的name,值則爲對應的數據。
  注意,FILES 只有在請求的方法爲POST 且提交的<form> 帶有enctype="multipart/form-data" 的狀況下才會
   包含數據。不然,FILES 將爲一個空的相似於字典的對象。


9.HttpRequest.COOKIES

  一個標準的Python 字典,包含全部的cookie。鍵和值都爲字符串。



10.HttpRequest.session

   一個既可讀又可寫的相似於字典的對象,表示當前的會話。只有當Django 啓用會話的支持時纔可用。
    完整的細節參見會話的文檔。


11.HttpRequest.user(用戶認證組件下使用)

  一個 AUTH_USER_MODEL 類型的對象,表示當前登陸的用戶。

  若是用戶當前沒有登陸,user 將設置爲 django.contrib.auth.models.AnonymousUser 的一個實例。你能夠經過 is_authenticated() 區分它們。

    例如:

    if request.user.is_authenticated():
        # Do something for logged-in users.
    else:
        # Do something for anonymous users.


       user 只有當Django 啓用 AuthenticationMiddleware 中間件時纔可用。

     -------------------------------------------------------------------------------------

    匿名用戶
    class models.AnonymousUser

    django.contrib.auth.models.AnonymousUser 類實現了django.contrib.auth.models.User 接口,但具備下面幾個不一樣點:

    id 永遠爲None。
    username 永遠爲空字符串。
    get_username() 永遠返回空字符串。
    is_staff 和 is_superuser 永遠爲False。
    is_active 永遠爲 False。
    groups 和 user_permissions 永遠爲空。
    is_anonymous() 返回True 而不是False。
    is_authenticated() 返回False 而不是True。
    set_password()、check_password()、save() 和delete() 引起 NotImplementedError。
    New in Django 1.8:
    新增 AnonymousUser.get_username() 以更好地模擬 django.contrib.auth.models.User。

*/

request經常使用方法

/*

1.HttpRequest.get_full_path()

  返回 path,若是能夠將加上查詢字符串。

  例如:"/music/bands/the_beatles/?print=true"


2.HttpRequest.is_ajax()

  若是請求是經過XMLHttpRequest 發起的,則返回True,方法是檢查 HTTP_X_REQUESTED_WITH 相應的首部是不是字符串'XMLHttpRequest'。

  大部分現代的 JavaScript 庫都會發送這個頭部。若是你編寫本身的 XMLHttpRequest 調用(在瀏覽器端),你必須手工設置這個值來讓 is_ajax() 能夠工做。

  若是一個響應須要根據請求是不是經過AJAX 發起的,而且你正在使用某種形式的緩存例如Django 的 cache middleware,
   你應該使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 裝飾你的視圖以讓響應可以正確地緩存。

*/

 

1.2視圖響應對象

HttpResponse響應體 瀏覽器

views

from django.shortcuts import render

# Create your views here.

from django.shortcuts import HttpResponse
def index(request):
    print("method", request.method) #告訴你這是次GET請求
    print(request.GET)
    #print(request.GET("name"))
    print(request.POST)

    print(request.path)  #只能拿到路徑
    print(request.get_full_path()) #既能夠拿到數據,又能夠拿到路徑

    #return HttpResponse("<h1>ok</h1>") #HttpResponse就是一個響應體的意思;返回一個字符串;本質返回的就是一個HttpResponse
    import time
    ctime = time.time() #怎麼把這個變量放到頁面呢?


    return render(request, "index.html",{"timer":ctime})#index.html是模板文件;從數據庫取出來的參數、變量怎麼放在模板Html裏邊呢,這就涉及到render第三個參數了
#render渲染的時候把模板文件按照模板語法進行渲染成一個html文件發給瀏覽器(含有模板語法的html文件再也不是Html文件了,而是叫模板文件了。)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="" method="post">  {#action裏邊能夠加http://127.0.0.1:8000/index/也能夠加index/都是默認會生成#}
        姓名<input type="text" name="name">
        年齡<input type="text" name="age">
        <input type="submit">
    </form>
<p>{{ timer }}</p>  {#模板語法,模板文件;#}
</body>
</html>

 二、模板語言

2.1模板語法之變量

views.py

from django.shortcuts import render

# Create your views here.

def index(request):
    '''模板語法只有2個:
    渲染變量:{{}} 1.深度查詢--->>句點符;2.過濾器
    渲染標籤:{% %}
    :param request:
    :return:
    '''
    name = "simon"
    i = 10      #整型
    l = [1,2,3] #列表 
    info = {"name":"simon", "age":22} #字典
    b = True    #布爾
    class Person(object):   
        def __init__(self, name, age):
            self.name = name
            self.age = age
    alex = Person("alex",33)  #對象
    egon = Person("egon",38)

    person_list = [alex, egon] 

    #return render(request, "index.html", {"name":name})
    return render(request, "index.html", locals()) #locals是局部變量的意思,這樣就不用一個個去對應了;它會把這些局部變量直接傳給模板,它傳的時候就是按照{「name」:name} {"alex":alex}這種方式傳的

 

index.py

<!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>     #我想要第2個元素
    <p>{{ info.name }}</p> #字典下的name那個鍵
    <p>{{ alex.age }}</p>  #alex這個變量對象
    <p>{{ person_list.1.age }}</p> #person_list中第二我的的年齡

</body>
</html>

2.2模板之過濾器

{{obj|filter__name:param}}

 

default
若是一個變量是false或者爲空,使用給定的默認值。不然,使用變量的值。例如:{{ value|default:"nothing" }}
length
返回值的長度。它對字符串和列表都起做用。例如:{{ value|length }}
若是 value 是 ['a', 'b', 'c', 'd'],那麼輸出是 4。
filesizeformat
將值格式化爲一個 「人類可讀的」 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:{{ value|filesizeformat }}
若是 value 是 123456789,輸出將會是 117.7 MB。  
date
若是 value=datetime.datetime.now(){{ value|date:"Y-m-d" }}  
slice
若是 value="hello world"   {{ value|slice:"2:-1" }}
truncatechars
若是字符串字符多於指定的字符數量,那麼會被截斷。截斷的字符串將以可翻譯的省略號序列(「...」)結尾。
參數:要截斷的字符數。例如:
{{ value|truncatechars:9 }}
safe
Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統,後臺添加的文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本,若是自動轉義的話顯示的就是保護HTML標籤的源文件。爲了在Django中關閉HTML的自動轉義有兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的沒必要轉義。好比:
value="<a href="">點擊</a>"     {{ value|safe}}
這裏簡單介紹一些經常使用的模板的過濾器
https://yiyibooks.cn/translate/django_182/ref/templates/builtins.html#ref-templates-builtins-tags

 

views

from django.shortcuts import render

# Create your views here.

def index(request):
    '''模板語法:
    變量:{{}} 1.深度查詢 句點符;2.過濾器
    標籤:{% %}
    :param request:
    :return:
    '''
    ##########過濾器 
    import datetime
    now = datetime.datetime.now()

    file_size = 123456789

    text = "hello python hi luffycity go java linux"
    link = "<a href=''>click</a>"

    #return render(request, "index.html", {"name":name})
    return render(request, "index.html", locals()) #locals是局部變量的意思

 

index.html

   <h3>過濾器</h3>
    <p>{{ now|date:"Y-m-d" }}</p>               #date是它自帶的值,只能是這個。now --->>給它替換成 "Y-m-d"
    <p>{{ person_list|default:"數據爲空" }}</p>  #數據爲空的時候
    <p>{{ file_size|filesizeformat }}</p>       #字節大小,78M
    <p>{{ text|truncatechars:9 }}</p>          {# 按照字節數截斷#}
    <p>{{ text|truncatewords:3 }}</p>          {# 按照單詞數截斷#}
    <p>{{ link|safe }}</p>                     {# 不加safe,django爲了安全性(<script> alert(123)</script>)會把含有特殊字符的符號轉義#}
    <p>{{ l.0|add:100 }}</p>                   {# 1+100=101,加法過濾器#}
    <p>{{ info.name|upper }}</p>                #大寫

2.3模板語法之標籤

views

from django.shortcuts import render, HttpResponse

# Create your views here.

def index(request):
    '''模板語法:
    變量:{{}} 1.深度查詢 句點符;2.過濾器 {{val|filter_name}}
    標籤:{% %}
    :param request:
    :return:
    '''

    #########標籤  
    user = "alex"  #user有值
    #return render(request, "index.html", {"name":name})
    return render(request, "index.html", locals()) #locals是局部變量的意思

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

    return render(request, "login.html")

index

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    
    <h4>for標籤</h4>
    {% for i in l%}
    <p>{{ i }}</p>  #循環出列表l裏邊的 1 2 3 
    {% endfor %}

    {% for i in info %}
    <p>{{ i }}</p>  #i就是字典裏的key
    {% endfor %}

    {% for person in person_list %}
    <p>{{ forloop.counter0 }} {{ person.name }} , {{ person.age }}</p>  ##每一個人的(前邊有個序列號,它必須放到循環裏邊)名字、年齡
    {% empty %} #若是列表爲空能夠把這個寫上,再加個p標籤
     <p>列表爲空</p>
    {% endfor %}


#############if標籤 {% if user %} #若是user是登陸狀態 <p> <a href="">hi {{ user }}</a> {# user變量有值就是登陸狀態,要渲染的標籤 #} <a href="">註銷</a> </p> {% else %} <p> <a href="">登陸</a> <a href="">註冊</a> </p> {% endif %}

##############with標籤 {% with person_list.1.name as n %} {#進行替換#} {{ n }} {{ n }} {% endwith %} </body> </html>

login

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="" method="post">
      {% csrf_token %}  {# 第一次發post請求,知道你沒這個鍵值對就能夠把你攔截了,一刷新這個頁面就有了,#}
{#                         再提交時第二次給服務器發post請求,帶着這個鍵值就能夠經過;這個值是存儲在服務器上的,專門的代碼給你攔截作判斷的#}
        <input type="text" name="user">
        <input type="submit">
    </form>
</body>
</html>

咱們加的這個 {% csrf_token %} render方法給渲染成了這個Html頁面,在post提交的時候是提交了input兩個鍵值對。之後只要是提交post請求均可以加上去

csrf_token至關於在放了一個input標籤(<input type="text" >,值是一個隨機字符串)把這個問題給解決了

 

<input type="hidden" name="csrfmiddlewaretoken" value="khvxtlENbJs6MAfUey7lClorAnRlEAuyabyIRKhLqcvR3uds7dw8LzsUqWJrN1Aw">

 

   

 

2.4自定義標籤

 

在my_tag_filter

from django import template

register = template.Library()
@register.filter #加個裝飾器
def multi_fliter(x, y): #自定義過濾器 i表明過濾器前邊的渲染變量,y是參數;最大定義2個形參
    return x*y

@register.simple_tag()  #自定義標籤;能夠傳3個參數,沒有參數限制
def multi_tag(x, y, z):
    return x*y*z

index裏邊的部分

   <h4>自定義過濾器,標籤</h4>
   {% load my_tag_filter %}   {#把它load引入進來 把你寫的文件導入進來#}
    <p>{{ i|multi_fliter:20 }}</p> {# i*20 i就是那個x,y是20 ;調用的時候最多傳2個參數這就是multi_fliter的侷限性#}

    <p>{% multi_tag 7 9 2%}</p>  {# 自定義一個標籤,標籤的調用 ;自定義標籤沒有限制,雖然參數靈活了,可是不能放在if裏邊進行條件判斷,由於它須要加%#}

    {% if i|multi_fliter:10 > 100 %} #判斷i*10是否大於100,(i=10) 但multi_tag就不能放在if判斷裏邊去了;這兩個各有優缺點。
    <p>100</p>                       #是就顯示100
    {% else %}
    <p>{{ i }}</p>                   #不然就顯示i
    {% endif %}

 2.5 繼承

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

advertise.html(bootstrap面板部分)

        <div class="action">
                <div class="panel panel-danger">
                <div class="panel-heading">Panel heading without title</div>
                <div class="panel-body">
                Panel content
                </div>
            </div>
            <div class="panel panel-warning">
                <div class="panel-heading">Panel heading without title</div>
                <div class="panel-body">
                Panel content
                </div>
            </div>
            <div class="panel panel-success">
                <div class="panel-heading">Panel heading without title</div>
                <div class="panel-body">
                Panel content
                </div>
            </div>
        </div>

模板bases.html(模板頁面)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
  <!-- <title>Title</title> -->
    {% block title %} {#留下Title盒子,等繼承者去繼承;你寫個title,繼承者想繼承就繼承,不想繼承就按照父本這樣子;能夠留多個盒子 #}
    <title>base</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>
        *{
            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 %} ##裏邊加一個可擴展的盒子,留給繼承者去擴展這個盒子,你能夠本身去寫這一部分;若是你擴寫了就覆蓋了這個盒子,用你本身的,沒有就用這個了哦
                <h1>content</h1>
            {% endblock %}
        </div>
    </div>
</div>

</body>
</html>

這個模版,咱們把它叫做 base.html, 它定義了一個簡單HTML骨架。「子模版」的工做是用它們的內容填充空的blocks。

在這個例子中, block 標籤訂義了2個能夠被子模版內容填充的block。 block 告訴模版引擎: 子模版可能會覆蓋掉模版中的這些位置。

子模版可能看起來是這樣的:

index

{% extends 'base.html' %} {#先繼承base,必須寫在首行,否則它不知道block是什麼意思 跟include不同,它有它本身獨特的優點#}

{% block title %}
<title>index</title>
{% endblock %}

{% block con %}   {#base裏邊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>

            <h3>過濾器</h3>
            <p>{{ now|date:"Y-m-d" }}</p>
            <p>{{ person_list|default:"數據爲空" }}</p>
            <p>{{ file_size|filesizeformat }}</p>
            <p>{{ text|truncatechars:9 }}</p>  {# 按照字節數#}
            <p>{{ text|truncatewords:3 }}</p> {# 按照單詞數#}
            <p>{{ link|safe }}</p> {# 不加safe,django爲了安全性會把含有特殊字符的符號轉義#}
            <p>{{ l.0|add:100 }}</p> {# 1+100=101#}
            <p>{{ info.name|upper }}</p>
            <hr>

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

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

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


            {% if user %}
            <p>
               <a href="">hi {{ user }}</a>  {# user變量有值就是登陸狀態,要渲染的標籤#}
                <a href="">註銷</a>
            </p>
            {% else %}
                <p>
                    <a href="">登陸</a>
                    <a href="">註冊</a>
                </p>
            {% endif %}

            {% with person_list.1.name as n %}  {#進行替換#}
            {{ n }}
            {{ n }}
            {% endwith %}

            <hr>
            <h4>自定義過濾器,標籤</h4>
           {% load my_tag_filter %}   {# 把你寫的文件導入進來#}
            <p>{{ i|multi_fliter:20 }}</p> {# i*20 ;調用的時候最多傳2個參數這就是multi_fliter的侷限性#}

            <p>{% multi_tag 7 9 2%}</p>  {# 自定義一個標籤,標籤的調用 ;自定義標籤沒有限制,雖然參數靈活了,可是不能放在if裏邊進行條件判斷,由於它須要加%#}

            {% if i|multi_fliter:10 > 100 %}
            <p>100</p>
                {% else %}
                <p>{{ i }}</p>
            {% endif %}
{% endblock %}

order

{% extends 'base.html' %}

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

{% block con %}
{{ block.super}} {#這樣就繼承了父類,還引用父類裏邊的內容,又重寫了本身#}
<h4>訂單</h4>
{% endblock con%} {#能夠把名字加上就好區分了,誰對應誰,就是con要和上邊的con對應上 #}

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

那時,模版引擎將注意到 base.html 中的2個 block 標籤,並用子模版中的內容來替換這些block。

這裏是使用繼承的一些提示:

  • 若是你在模版中使用 {% extends %} 標籤,它必須是模版中的第一個標籤。其餘的任何狀況下,模版繼承都將沒法工做。

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

  • 若是你發現你本身在大量的模版中複製內容,那可能意味着你應該把內容移動到父模版中的一個 {% block %} 中。

  • If you need to get the content of the block from the parent template, the {{ block.super }} variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using {{ block.super }} will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.

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

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

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

  • 不能在一個模版中定義多個相同名字的 block 標籤。
相關文章
相關標籤/搜索