Django從入門到放棄一 -- 基礎部分

參考地址:http://www.cnblogs.com/yuanchenqi/articles/7629939.html

一、什麼是Django

  Django是一個Web應用程序的框架。

  預備知識:1、python基礎    2、數據庫    3、前端( jquey + bootstrap )

 

1.1、Django請求生命週期

 

二、Web請求的本質

    CS架構:client   ---   server        #客戶端 -- 服務端
    BS架構:browser  ---  server     #瀏覽器 -- 服務端

 

三、MTV模型

   代表模型(Model): 負責業務對象和數據庫的關係映射(ORM)。與數據庫交互

   代表模板(Template): 負責如何把頁面(根據請求,決定給用戶什麼樣的頁面)展示給用戶(HTML)。

   代表視圖(View): 負責業務邏輯,並在適當的時候調用Model和Template(把數據封裝成模板的樣子返還給用戶)

圖解MTV模型:

  URL控制器:什麼路徑 ( login | admin | index 等) 交給什麼函數去處理。

 

四、Django學習過程

4.1、下載與命令  -- 在命令行操作的方式  ( django是依賴於Python庫的,用什麼pip版本下載的,django就存在於對應版本的Python庫的Scripts目內[django-admin.exe] )

  下載:        pip3 install django==1.11.1    #最新版本django-2.1.4

  卸載:        pip3 uninstall django-1.11.1  

  創建項目:django-admin startproject mysite    #其中mysite爲項目名稱(項目名可以修改)

  創建一個應用:python3 manage.py startapp app01  #app01爲應用名稱

  項目啓動命令:python3 manage.py runserver  IP+PORT   #默認是127.0.0.1:8000

                  mysite 項目包含的:

                       1 --- mysite     #和項目名稱同名的目錄(不能更改名稱)

                             --- settings    項目配置文件

                             --- urls           路徑與視圖函數的映射關係

                             --- wsgi         封裝的socket

                      2 --- manage.py     Django項目進行交互的腳本

                      3 --- app01 項目應用   #python3 manage.py startapp app01(創建一個應用)

                             --- models     數據庫操作

                             --- views        視圖函數

                      4 --- app02 項目應用   #python3 manage.py startapp app02(創建一個應用)

                             --- models     數據庫操作

                             --- views        視圖函數

                     5 --- templates   #存放模板的文件夾(名稱必須爲templates)

                             --- index.html

                             --- login.html

 

4.3、查看django版本號  pip show django

 

4.4、在pycharm中創建Django項目的方式

方式一:使用現有的Python(版本)環境

方式二:創建一個新的Python虛擬環境

make available to all projects:表示創建的項目工程可以被其他項目使用

inherit global site-packages:繼承本地的Python版本庫


  五.URL控制器  urls.py -- Django實踐  

  URL:  協議://IP(域名):端口(80)/路徑?GET參數

  URL的功能:反映URL的路徑和視圖函數的映射關係

  5.1、URL的簡單使用 -- 在urls.py文件配置

from app01 import views  # 指定路徑

urlpatterns = [
    url(r'^timer/', views.timer),   #views.timer(request) django會幫我們把http請求頭的信息拿到,默認傳進去。
]

  然後在應用目錄APP01的views.py文件裏,定義timer

from django.shortcuts import render,HttpResponse
# HttpResponse爲封裝響應體的類

def timer(request):  # request請求信息對象
    import time
    ctime=str(time.time())
    return HttpResponse(ctime)   # 執行timer函數,[HttpResponse這個類在實例化的時候需要傳入的值爲字符串類型,所以ctime要設置爲字符串類型]

訪問:http://127.0.0.1:8000/timer/ 拿到當前機器的時間!

 

5.2、URL的無名分組 --  一般用來傳URL路徑裏面的某一個參數,或者說是獲取URL路徑裏面的某一個參數。

# 在urils.py裏對應的配置。
from app01 import views

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^articles/(\d{4})/$', views.article_year),    
]                                                       
# \d{4}:表示4位數字
# (\d{4}) :表示接收瀏覽器URL路徑裏面的某一個值,接收到的值會傳給views.article_year(request,(\d{4})),那麼在後端的代碼裏面article_year函數裏面也要傳2個參數。


# 在views.py裏對應的配置。
def article_year(request,year):
    #數據庫查詢
    return HttpResponse(year)

 

5.2、URL的有名分組  --  根據定義的關鍵字傳參 -- 相當於關鍵字傳參 -- (?P<year>\d{4}) 只能接收數字

# 在urils.py裏對應的配置。
from app01 import views

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', views.article_year_month), 
    # year接收傳入的第一個值並賦值給year(year=1999),month接收傳入的第二個值並賦值給month(month=12)
]                                                       

# 在views.py裏對應的配置。
def article_year_month(request,year,month):
    #數據庫查詢
    return HttpResponse(year+"/"+month)

 

5.3、URL的分發 --  每個應用下單獨定義urls,只需要在項目目下做總的分發,實現解耦效果。

# 在項目目錄下的urls.py文件內定義

from django.conf.urls import include, url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^app01/',include('app01.urls'))        # 定義訪問app01應用的走app01目錄下urls.py文件
]

# 那麼在app01目錄下urls.py文件定義如下:實現解耦的效果

from django.conf.urls import include, url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    # 無名分組
    url(r'^articles/(\d{4})/(\d{2})/$', views.article_year_month),
    # 有名分組
    url(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', views.article_year_month),
]

# 在views.py文件中的代碼如下:
from django.shortcuts import render,HttpResponse

def article_year_month(request,year,month):
    return HttpResponse(year+":"+month)

# 訪問的URL就必須加上app01前綴,否則無法訪問
# http://127.0.0.1:8000/app01/articles/2005/19/

 

5.4、URL的反射  --  給固定的URL路徑起一個別名,那麼在使用路徑時用這個別名即可。無論這個URL的路徑在urls.py中如何修改,只要在前端html中定義"action={% url 'login' %}",那麼"{% url 'login' %}"就總能獲取到urls.py中定義的URL路徑(前端HTML不需要修改對應的路徑)。--可參照 (7.2、渲染URL標籤 {% %} )

在Html中寫法:<form action="{% url 'login' %}" method="post">
在在Python中寫法:url(r'^login/',views.login,name="login"),  # name="login" 定義一個別名叫"login"

# 例子:
# 在Python中:views.py文件中定義
urlpatterns = [
    url(r'^login/',views.login,name="login"),  

在 Html中:timer.html中定義
<form action="{% url 'login' %}" method="post"></form>  
  # 在html中,首先會查找有沒有模板語法,如果沒有的話,那麼就直接丟給瀏覽器去讀取html的內容了。
  # 如果有模板語法,那麼根據模板語法的內容,去全局的urls.py文件中找一個叫"login"的別名字符串。
  # 找到"login"這個別名字符串後,會把這個別名對應的URL動態的獲取,然後放在html中的action裏面,然後交給瀏覽器去讀取html中的action的內容。
]

 

例子:實現用戶的登錄及認證功能

# 前端HTML:
<body>

<form action="/login/" method="post">        {# login默認訪問當前請求URL下的IP+端口/login/ #}  {# action: 用戶提交後,請求到後端的地址 #}  {# method="post": 提交請求爲"POST"請求 #}
    用戶名: <input type="text" name="user">  {# 這個user是用來:獲取用戶輸入的"用戶名" #}
    密碼: <input type="text" name="pwd">     {# 這個pwd是用來:獲取用戶輸入的"密碼" #}
    <input type="submit">                    {# submit是一次提交 #}
        
</form>

</body>

# 後端代碼:
# 一、urls.py文件內

from app01 import views
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^timer/', views.timer),

    # 二合一版本
    url(r'^login/', views.login),
]

# 二、views.py文件內

from django.shortcuts import render,HttpResponse
def login(request):
    method=request.method  # request.method 拿到的是用戶請求一個頁面的方式"GET"或者"POST"
    if method == "GET":    # 判斷用戶的請求方式
        return render(request,"login.html")  # 如果爲"GET",則返回"login.html"
    else:
        user=request.POST.get("user")  # 通過“request.POST.get”,拿到前端用戶輸入的"用戶名"
        pwd=request.POST.get("pwd")    # 通過“request.POST.get”,拿到前端用戶輸入的"密碼"
        # 校驗數據
        if user == "szq" and pwd == '123':
            return HttpResponse('登錄成功')
        # 響應
        return HttpResponse("登錄失敗")

 

  六.視圖語法  views.py

  6.1、request  -- 請求信息

# 在views.py文件裏面編輯:
# 然後訪問:http://127.0.0.1:8000/index/ 拿到如下信息!

def index(request):
    # 請求信息
    print(request.GET)     # 發送GET請求
    # <QueryDict: {'a': ['1']}>

    print(request.POST)    # 發送POST請求
    # < QueryDict: {} >

    print(request.method)  # 獲取本次請求的方式 "GET或POST"
    # GET

    print(request.path)    # 獲取本次請求的相對路徑
    # /index/

    print(request.get_full_path())    # 獲取本次請求的全部路徑(ip+port之後的路徑地址)
    # /index/?a=1

 

  6.2、HttpResponse  --  響應信息

    1、Django必須響應HttpResponse對象

    2、HttpResponse 響應字符串

# 使用例子,在views.py文件中:
def index(request):
    return HttpResponse("首頁!")

    3、render       響應模板(對應的html文件)

    4、redirect     重定向 -- 用戶登錄成功後,重定向到網站首頁!  (服務器讓瀏覽器重定向請求,瀏覽器相當於請求了2次服務器)

# 使用例子,在views.py文件中:
def login(request):
    if request.method=="GET":
       return render(request,'login.html')
    else:
       if 1:
       return redirect("/index/")  # 在這裏做了重定向跳轉,跳轉的路徑爲"/index/",觸發這次重定向之後,就會跳轉到http://127.0.0.1:8000/index/這個頁面。

 

  七.模板語法  templates -- 模板語法都是由render解析的  

   7.1、render方法的功能:
      方式一:return render(request,"login.html")
           按着settings指定路徑找到對應的login.html,讀取文件內容,構建return HttpResponse(文件字符串)

      方式二:return render(request,"timer.html",{"ctime":ctime, "name":name, "age":age,})
           按着settings指定路徑找到對應的timer.html,讀取文件內容,進行渲染,把文件字符串中所有的{{}}的內容按着{"ctime":ctime, "name":name, "age":age,}的方式進行替換,將新的替換字符串構建return HttpResponse(文件字符串)
 

   7.2、模板語法分爲:

      1.變量 :1)深度查詢,2)過濾器 

      2.標籤

  1、模板語法之變量的用法 {{ }} 小例子:

# 渲染變量的
在Html中寫法:<form action="{{ctime}}" method="post">
在在Python中寫法:return render(request,"timer.html",{"ctime":ctime,"name":name,"age":age,})

# 例子:
# 在Python中:views.py文件中定義
def timer(request):
    import time
    ctime=str(time.time())
    name="sudada"
    age=18
    return render(request,"timer.html",{  # render能夠找到"timer.html"文件,是因爲在setting,py (裏面的TEMPLATES定義了'DIRS': [os.path.join(BASE_DIR, 'templates'))。django會從全局變量裏面找到templates目錄]
                    "ctime":ctime,  #"ctime"是給templates裏面的timer.html用的,而ctime取得是當前文件下的ctime
                    "name":name,    # 同"ctime"一樣
                    "age":age,      # 同"ctime"一樣
                })

在 Html中:timer.html中定義
<body>
<h3>當前時間: {{ ctime }}</h3>    # 調用後端裏面的"ctime"
<h3>My name is: {{ name }}</h3>  # 同上
<h3>My age is: {{ age }}</h3>    # 同上
</body>

  2、模板語法之標籤{% %}的用法 小例子:渲染URL標籤 -- 在Html模板裏面對URL進行渲染  {% %}

# 渲染URL標籤的
在Html中寫法:<form action="{% url 'login' %}" method="post">
在在Python中寫法:url(r'^login/',views.login,name="login"),  # name="login" 定義一個別名叫"login"

# 例子:
# 在Python中:views.py文件中定義
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^login/',views.login,name="login"),  

在 Html中:timer.html中定義
<form action="{% url 'login' %}" method="post"></form>  
  # 在html中,首先會查找有沒有模板語法,如果沒有的話,那麼就直接丟給瀏覽器去讀取html的內容了。
  # 如果有模板語法,那麼根據模板語法的內容,去全局的urls.py文件中找一個叫"login"的別名字符串。
  # 找到後會把這個別名動態的獲取,然後放在html中,然後交給瀏覽器去讀取html的內容。
]

 

 7.3、模板語法(變量)的使用:深度查詢

  在python中的用法:

  如下:定義了"name" "l" "dic"等變量,以及類"Animal"等。

def template(request):
    '''
    模板語法:
        變量
            --- 深度查詢
            --- 過濾器
    '''
    name="sudada"
    l=[11,22,33]
    dic={"name":"sudada","age":18,"sex":"male"}

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

    zzz=Animal("zzz",10)
    lll=Animal("lll",20)
    sss=Animal("sss",30)

    person_list=[zzz,lll,sss]

    return render(request,"templates.html",{"name":name,"l":l,"dic":dic,"person_list":person_list})
    # return render(request,"templates.html",locals())

  那麼在前端是如何調用的呢?   前端HTML代碼使用是效果展示:{{  }} 的方式調用Python裏面定義的變量

<p>{{ name }}</p>
# sudada 拿到變量name的賦值

<<---------分隔----------->>

<p>{{ l }}</p>
#[11, 22, 33] 拿到l列表裏面定義的所有值

<p>{{ l.0 }}</p>
#11 取l列表裏面定義的第一個值

<p>{{ l.1 }}</p>
#22 取l列表裏面定義的第二個值

<p>{{ l.2 }}</p>
#33 取l列表裏面定義的第三個值

<<---------分隔----------->>

<p>{{ dic.name }}</p>
#sudada 取字典裏面的第一個值

<p>{{ dic.age }}</p>
#18 取字典裏面的第二個值
 
<p>{{ dic.sex }}</p>
#male 取字典裏面的第三個值

<<---------分隔----------->>

<p>{{ person_list.0 }}</p>
#<app01.views.template.<locals>.Animal object at 0x000001AFD0655198> 拿到的是實例化的對象,可以看出定義的類爲"Animal"

<p>{{ person_list.0.name }}</p>
#zzz 拿到的是列表person_list裏面實例化後的對象name對應的值,0表示列表裏面的第一個對象,name表示對象name對應的值。

<p>{{ person_list.0.age }}</p>
#10 同上

<p>{{ person_list.1.name }}</p>
#lll同上

<p>{{ person_list.1.age }}</p>
#20同上

<p>{{ zzz.name }}</p>
# zzz 直接獲取對象zzz的name對應的值

<p>{{ zzz.age }}</p>
# 10 直接獲取對象zzz的age對應的值


  7.4、模板語法(變量)的使用:過濾器語法 {{val(變量)|filter_name(過濾器名字):參數}}  -- 更友好的顯示一些數據

  在python中的用法:

def template(request):    
    """
    過濾器的使用之語法:{{val(變量)|filter_name(過濾器名字):參數}}
    """
    number=100
    import datetime
    now=datetime.datetime.now()

    # book_list=["三國演義","金瓶梅"]
    book_list=[]
    file_size=12312311
    s="Hello World"
    article="asd,哈哈哈,asd,愛 asd asd 12 lasdj lqniuqg id bsmnc buqho namv uqbwi namsb iuqoiejlqkwbdbnmasb j"

    link="<a href=''>rick</a>"
    # return render(request,"templates.html",{"name":name,"l":l,"dic":dic,"person_list":person_list}) # 寫法一
    return render(request,"templates.html",locals())     # 寫法二
    # locals() == {"name":name,"l":l,"dic":dic,"person_list":person_list}

  那麼在前端是如何調用的呢?

  前端HTML代碼使用是效果展示:

<h4>過濾器</h4>
<p>{{number|add:20}}</p>               
# number變量名,"|"固定寫法,add表示加法,":"固定寫法,20表示數字。表示在number=100的基礎上在加20

<p>{{ now|date:"Y-m-d h:i" }}</p>      
# 原本"Dec. 30, 2018, 11:54 p.m."的格式加上過濾器date:"Y-m-d h:i"後,變成了"2018-12-30 11:54"

<p>{{ book_list|default:"沒有符合條件的數據" }}</p>   
# 當book_list=[]爲空的時候,默認顯示"沒有符合條件的數據",當book_list=["三國演義","金瓶梅"]裏面存在值的時候,就顯示列表裏面的值。

<p>{{ file_size|filesizeformat }}</p>  
# 把file_size=123123123換算成字節大小,顯示的效果爲"117.4 MB"(格式單位自動調節),可以一眼看出文件有多大。

<p>{{ s|slice:"0:3" }}</p>             
# 對s="Hello World" 切片(顧頭不顧尾),取"0:3"的值

<p>{{ s|slice:"0::2" }}</p>            
# 對s="Hello World" 切片(顧頭不顧尾),每隔2個單位取一個值

{#展示一篇文章前面的一部分內容#}
<p>{{ article|truncatechars:10 }}</p>  
# 展示一片文章的前7個字符(後面會默認加...三個字符)
<p>{{ article|truncatewords:3 }}</p>   
# 展示一片文章的前3個單詞(默認以空格爲單詞之間的分隔符分隔符)

<p>{{ link|safe }}</p>   
# Django的安全機制會將link="<a href=''>rick</a>"標籤字符串進行轉譯,那麼需要加上一個safe的過濾器,讓他保持原意

 

7.4、自定義標籤和過濾器

  1、在settings中的INSTALLED_APPS配置當前app01(項目名),不然django無法找到自定義的simple_tag.

  2、在app01中創建templatetags模塊 (模塊名只能是templatetags)

  3、創建任意 .py 文件,如:my_tags.py,並自定義過濾器函數和標籤函數

from django import template
from django.utils.safestring import mark_safe
 
register = template.Library()   #register的名字是固定的,不可改變
 
 
@register.filter
def filter_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)

4、在使用自定義simple_tag和filter的index.html文件中導入之前創建的 my_tags.py

# 在index.html文件中:
<body>

{% load my_tag %}

</body>

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

# 在index.html文件中:
<body>

{% load my_tag %}         # 導入自定義的過濾器
{{ 3|filter_multi:4 }}    # 3:表示第一個參數,4:表示第二個參數,這種方式只能傳2個值。my_tags.py中的filter_multi函數會接受這2個值,並做下一步處理
{% my_input 'id_test' 'class_test' %}   # 給自定義標籤my_input傳值。

</body>

 

 7.5、模板語法(標籤)的使用:for標籤 {%%} -循環渲染

在Python裏面的用法:

def template(request): 
    ###########標籤############
    book_list = ["三國演義","金瓶梅","西遊記"]
    dic={"name":"sudada",
         "age":18,
         "sex":"male",
         }
    return render(request,"templates.html",locals())

    #或者使用這種方式
    return render(request,"books.html",{"book_list":book_list})  

    # {"book_list":book_list} == locals()

  前端HTML代碼使用是效果展示:

{% for n in book_list %}   # for 循環開始,針對列表循環
    <p>{{ n }}</p>
{% endfor %}               # for 循環結束,固定語法
三國演義
金瓶梅
西遊記


{% for book in book_list %}
    <li>{{ book }}</li>
{% endfor %}
*三國演義
*金瓶梅
*西遊記


{% for i in book_list %}
    <p>{{ forloop.counter }}  {{ i }}</p>
{% endfor %}
1 三國演義
2 金瓶梅
3 西遊記


{% for key in dic %}     # 針對字典循環
    <p>{{ key }}</p>     # 拿到的值爲字典的key
{% endfor %}
name
age
sex


{% for key,value in dic.items %}     # 針對字典裏面的key和value的循環
    <p>{{ key }}  {{ value }}</p>
{% endfor %}
name sudada
age 18
sex male

 

 7.6、模板語法(標籤)的使用:if標籤-if條件判斷

 在Python裏面的用法:

def template(request): 
    ###########if 條件判斷標籤############
    score=90
    num_list=[123,34,546,8,98,2,344123,30,435457,65,456,4]

    return render(request,"templates.html",locals())

  前端HTML代碼使用是效果展示:

<p>if 標籤</p>

{% if score > 90 %}
<p>very good</p>
{% elif score > 60 %}
<p>good</p>
{% else %}
<p>NO</p>
{% endif %}
# 輸出的值如下:
    good

<p>條件判斷大於50的數字</p>  # for循環裏面嵌套if條件判斷

{% for num in num_list %}
{% if num > 50 %}
    <p>{{ num }}</p>
{% endif %}
{% endfor %}
# 輸出的值如下:
    123
    546
    98
    344123
    435457
    65
    456

 

7.7、Django引入靜態文件

  1、首先在項目根路徑下創建 "static" 目錄,然後把靜態文件都放在這個目錄下。

  2、在settings.py文件的最後一行,新增"static"目錄

# 別名:之後在使用時,可以用別名代替實際路徑
STATIC_URL = '/static/'   # 這個配置是Django自帶就有的

# 文件的實際存在目錄,給Django使用的
STATICFILES_DIRS=[
    os.path.join(BASE_DIR,"static")
]

  3、在前端html文件中引用靜態文件

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>  # 引用免費CDN上面的js文件
    <script src='/static/jquery.js'></script>  # 引用static目錄下的靜態文件
</head>

 

7.8、Django模板的繼承 

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

  1、繼承的目的就是減少前端代碼冗餘

  2、Django模板繼承大體就是:先寫一個父類HTML,然後子類HTML繼承父類HTML的代碼的方式。 具體如下:

    2.1 父類HTML ,先寫一堆父類HTML代碼,然後定義一個 "block" (具體寫法爲:{% block Title %} )。"block"就是一個子類HTML可重寫代碼的部分。

{# 父類HTML文件base.html #}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
  
    {# 繼承的寫法#}
    {% block Title %}
        <title>Title</title>
    {% endblock %}

    <meta name="viewport" content="width=device-width,initial-scale=1">
    {# 使用這套佈局方式 #}
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .header{    {# 設置頁面頭部格式 #}
            width: 100%;
            height: 60px;
            background-color: #369;
        }
    </style>

</head>
<body>

<div class="header"></div>

<div class="container">
    <div class="row">

        <div class="col-md-3">
            <div class="panel panel-warning">
              <div class="panel-heading">
                <h3 class="panel-title">Panel title</h3>
              </div>
              <div class="panel-body">
                Panel content
              </div>
            </div>
        </div>
        <div class="col-md-9">
            {% block centent %}   {# block的功能:當其他的html文件繼承base.html(當前文件)時,可以重寫centent的內容。 #}  {# centent這個名字不是固定寫法 #}
                <p>這是一個盒子</p>
            {% endblock %}

        </div>

    </div>
</div>


</body>
</html>

    2.2 子類HTML ,繼承父類HTML的方法 (只能繼承一個父類HTML模板)

       1). 在子類HTML中,使用{% extends "base.html" %} 明確繼承哪個父類HTML

       2). 在子類HTML中,使用{% block centent %} 自定義代碼

{# 子類HTML文件order.html #}
{% extends "base.html" %}    {# 繼承base.html文件,必須放在第一位 #}

{% block centent %}     {# 然後重寫block裏面的內容 #}
    <h3>訂單列表</h3>
        {% for order in order_list %}
            <p>{{ order }}</p>
        {% endfor %}
{% endblock %}

 

  3、在子類HTML中使用{% block centent %}重寫HTML後,還想要顯示父類HTML中的{% block centent %},這種需要該如何實現。

{% extends "base.html" %}

{% block centent %}
    <h3>商品列表</h3>
        {% for shopper in shopper_list %}
            <p>{{ shopper }}</p>
        {% endfor %}

        <div>{{ block.super }}</div>   {# 寫一個div標籤,然後加上"{{ block.super }}"就可以了 #}

{% endblock %}

 

  4、使用繼承的一些注意事項

1).如果你在模版中使用 {% extends %} 標籤,它必須是模版中的第一個標籤。其他的任何情況下,模版繼承都將無法工作。

2).在base模版中設置越多的 {% block %} 標籤越好。請記住,子模版不必定義全部父模版中的blocks,所以,你可以在大多數blocks中填充合理的默認內容,然後,只定義你需要的那一個。多一點鉤子總比少一點好。

3).如果你發現你自己在大量的模版中複製內容,那可能意味着你應該把內容移動到父模版中的一個 {% block %} 中。

4).爲了更好的可讀性,你也可以給你的 {% endblock %} 標籤一個 名字 。例如:
          {% block content %}
          ...
         {% endblock content %}  

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

6).最後,請注意您並不能在一個模版中定義多個相同名字的 block 標籤。這個限制的存在是因爲block標籤的作用是“雙向”的。這個意思是,block標籤不僅提供了一個坑去填,它還在 _父模版_中定義了填坑的內容。如果在一個模版中有兩個名字一樣的 block 標籤,模版的父模版將不知道使用哪個block的內容。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章