創(chuàng)建頁面:學習筆記主頁
三個階段:定義URL,編寫視圖和編寫模板
每個URL都被映射到特定的視圖——視圖函數(shù)獲取并處理頁面所需的數(shù)據(jù)。通常使用模板來渲染頁面,而模板定義頁面的總體結構
映射URL:
打開learning_log的urls.py
#導入一個模塊和一個函數(shù),以便對管理網站的URL進行管理
from?django.contrib?import?admin
from?django.urls?import?path
#定義變量urlpatterns
urlpatterns?=?[
? ? #admin.site.urls 該模塊定義了可在管理網站中請求的所有URL
????path('admin/',?admin.site.urls),
]
我們需要包含learning_logs的URL,因此添加:
from?django.contrib?import?admin
from?django.urls?import?path,include
#定義變量urlpatterns
urlpatterns?=?[
#admin.site.urls 該模塊定義了可在管理網站中請求的所有URL
????path('admin/',?admin.site.urls),
? ? path('',include('learning_logs.urls')),
]
在learning_logs中添加urls.py:
'''定義learning_logs的URL模式'''
from?django.urls?import?path
from?.?import?views??#?從當前所在文件夾中導入views.py
#?app_name將urls.py文件同項目中其他應用程序中同名文件夾分開來
app_name?=?'learning_logs'
urlpatterns?=?[
????#?實際的URL模式是對函數(shù)path()的調用
????path('',?views.index,?name='index'),
????'''三個參數(shù):第一個字符串,幫助Django正確地路由請求。
????收到請求的URL后,力圖將請求路由給一個視圖。搜索所有URL模式,進行匹配
????Django忽略項目的基礎URL主頁,因此空字符串''與基礎URL匹配,其它URL與這個模式不匹配'''
????'''第二個實參指定了調用view.py中哪個函數(shù),請求的URL與前述正則表達式匹配時,
????調用view.py中函數(shù)index()'''
????'''第三個實參將URL模式名稱指定為index,讓我們能夠在代碼其它地方引用,
????每當需要提供到這個主頁的鏈接時,都將使用這個名稱,而不編寫URL'''
]
編寫視圖:
learning_logs中views.py是執(zhí)行命令python manage.py startapp自動生成的
from?django.shortcuts?import?render
#?在這里創(chuàng)建視圖
添加為主頁編寫視圖的代碼:
from?django.shortcuts?import?render??#?根據(jù)視圖提供數(shù)據(jù)渲染響應
# 視圖函數(shù)
def?index(request):
????'''學習筆記的首頁'''
????return?render(request,?'learning_logs/index.html')
#URL請求與定義的模式匹配時,Django將在文件view.py中查找函數(shù)index(),將對象request傳遞給這個視圖函數(shù)
#rend()兩個實參:對象request以及一個可用于創(chuàng)建頁面的模板
編寫模板:
learning_logs中新建templates文件夾,里面再新建一個文件夾learning_logs,里面新建文件index.html
<p>Learning?Log</p>
<p>Learning?Log?helps?you?keep?track?of?your?learning,for?any?topic?you're?learning?about.</p>

創(chuàng)建其他頁面:
模板繼承:
1.父模板:創(chuàng)建base.html
#創(chuàng)建到主頁鏈接的段落? ? 標簽模板{% %}
#生成一個URL,與名為index的URL模式匹配。
#在本例中l(wèi)earnin_logs是一個命名空間,而index是該命名空間中一個名稱獨特的URL模式。
#這個命名空間來自于urls.py賦給app_name的值
<p>
????<a?href="{%?url?'learning_logs:index'?%}">Learning_Log</a>
</p>
#插入一對塊標簽,塊名為content,是一個占位符,其中包含信息由子模板指定
#子板塊并非必須定義父模塊中的每個塊,父模塊中可以使用任意多個塊來預留空間,而子模塊可根據(jù)需要定義相應數(shù)量的塊
{%?block?content?%}{%?endblock?content?%}
2.子模塊:重寫index.html 繼承base.html:
#子模塊第一行必須包括標簽{%?extends %},讓Django知道繼承哪個模塊,并導入
{%?extends?"learning_logs/base.html"?%}
#插入名為content的{%?block %}的標簽,以定義content塊
#不是從父模板繼承的內容都包含在content塊中,描述項目“學習筆記”的段落
{%?block?content?%}
<p>Learning?Log?helps?you?keep?track?of?your?learning,for?any?topic?you're?learning?about.</p>
#指出定義內容的結束位置
{%?endblock?content?%}
'''
模板繼承的優(yōu)點開始顯現(xiàn)出來:在子模板中,只需包含當前頁面特有的內容。簡化了每個模板,還容易修改,要修改共有的元素,只需在父模板中修改
'''
顯示所有主題的頁面:
顯示用戶創(chuàng)建的所有主題,一個需要使用數(shù)據(jù)的頁面
1.URL模式
定義所有主題的頁面的URL,修改learning_logs/urls.py:
……
urlpatterns?=?[
????#?實際的URL模式是對函數(shù)path()的調用
????path('',?views.index,?name='index'),
????#?顯示所有的主題
????path('topics/',?views.topics,?name='topics'),
]
這里在用于主頁URL的字符串參數(shù)中添加topics/,Django檢查請求的URL時,這個模式與如下URL匹配:基礎URL后面跟著topics ??稍谀┪舶备?,也可省略,但topics后面不能有任何東西。模式匹配請求都將交給views.py中函數(shù)topics()處理
2.視圖:
函數(shù)topics()需要從數(shù)據(jù)庫中獲取一些數(shù)據(jù),并將其交給模板。需要在views.py中添加:
from?django.shortcuts?import?render??#?根據(jù)視圖提供數(shù)據(jù)渲染響應
from?.models?import?Topic??#?導入所需數(shù)據(jù)相關聯(lián)的模型
#?在這里創(chuàng)建視圖
def?index(request):
????'''學習筆記的首頁'''
????return?render(request,?'learning_logs/index.html')
def?topics(request):??#?request從服務器收到的對象
????'''顯示所有的主題'''
????#?查詢數(shù)據(jù)庫——請求提供Topic對象,并根據(jù)屬性date_added排序
????topics?=?Topic.objects.order_by('date_added')
????#?定義一個將發(fā)送給模板的上下文。鍵:訪問數(shù)據(jù)名稱,值:發(fā)送給模板的數(shù)據(jù)
????context?=?{'topics':?topics}
????#返回?對象request?模板路徑?變量context
????return?render(request,?'learning_logs/topics.html',?context)
3.模板
顯示所有主題頁面模板接受字典context,以便使用topics()提供的數(shù)據(jù)。新建topics.html
{%?extends?"learning_logs/base.html"?%}?#繼承
{%?block?content?%}
????<p>Topics</p>
????<ul>????#無序列表,ul表示
????????{%?for?topic?in?topics?%}???#相當于for循環(huán)模板標簽
????????????<li>{{?topic?}}</li>????#項目列表項
????????{%?empty?%}?#如果列表為空
????????????<li>No?topics?have?been?added?yet.</li>
????????{%?endfor?%}????#循環(huán)結束位置
????</ul>
????{%?endblock?content?%}
修改父模板:
<p>
????<a?href="{%?url?'learning_logs:index'?%}">Learning_Log</a>?-? ? ? ? #增加-連字符
????<a?href="{%?url?'learning_logs:topics'?%}">Topics</a
</p>
{%?block?content?%}{%?endblock?content?%}

顯示特定主題的頁面:
1.URL模式learning_logs/urls.py:
urlpatterns?=?[
????#?實際的URL模式是對函數(shù)path()的調用
????path('',?views.index,?name='index'),
????#?顯示所有的主題
????path('topics/',?views.topics,?name='topics'),
????#?特定主題的詳細頁面
????path('topics/<int:topic_id>/',?views.topic,?name='topic'),
]
'''
'topics/<int:topic_id>/'????topics:查找在基礎URL后包含單詞topics的URL
/<int:topic_id>/? ? 與包含讓兩個斜杠內的整數(shù)匹配,并將這個整數(shù)存儲在一個名為topic_id的實參中
發(fā)現(xiàn)URL與這個模式匹配時,Django將調用視圖函數(shù)topic(),并將存儲在topic_id中的值作為實參傳遞給它
在這個函數(shù)中,將使用topic_id的值來獲取相應的主題
'''
2.視圖
函數(shù)topic()需要從數(shù)據(jù)庫中獲取指定的主題以及與之相關聯(lián)的所有條目:views.py
def?topic(request,?topic_id):??#?接受id捕獲的值
????topic?=?Topic.objects.get(id=topic_id)??#?獲取指定的主題
????entities?=?topic.entry_set.order_by('-date_added')??#?獲取相關聯(lián)的條目、并排序
????context?=?{'topic':?topic,?'entities':?entities}??#?主題、條目存儲在字典
????#?發(fā)送給模板topic.html
????return?render(request,?'learning_logs/topic.html',?context)
3.模板topic.html
{%?extends?"learning_logs/base.html"?%}
{%?block?content?%}
????<p>Topic:{{?topic?}}</p>? ? #顯示當前主題
????<p>Entries:</p>
????<ul>
????{%?for?entry?in?entries?%}? ? #項目列表遍歷
????????<li>
????????????<p>{{?entry.date_added|date:'M?d,?Y?H:i'?}}</p>? ? #條目時間戳? ? |模板過濾器 以''形式顯示
????????????<p>{{?entry.text|linebreaks?}}</p>? ? #完整的文本
????????</li>
????????{%?empty?%}
????????????<li>There?are?no?entries?for?this?topic?yet.</li>
????????{%?endfor?%}
????</ul>
????{%?endblock?content?%}
4.將顯示所有主題的頁面設置為鏈接 topics.html:
????????{%?for?topic?in?topics?%}
????????????<li>
????????????????<a?href="{%?url?'learning_logs:topic'?topic.id?%}">{{?topic?}}</a>
????????????</li>
????????{%?empty?%}
