全國(guó)咨詢(xún)/投訴熱線(xiàn):400-618-4000

首頁(yè)技術(shù)文章正文

Django框架中路由詳細(xì)介紹

更新時(shí)間:2019-09-12 來(lái)源:黑馬程序員 瀏覽量:

Django中路由的作用:

其本質(zhì)是URL與該URL要調(diào)用的視圖函數(shù)之間的映射,就是為告訴Django對(duì)客戶(hù)端發(fā)過(guò)來(lái)的某個(gè)URL應(yīng)該調(diào)用執(zhí)行哪一段邏輯代碼

路由基本的配置:

from django.conf.urls import url
# urlpatterns必須是一個(gè)由url()實(shí)例組成的Python列表
urlpatterns = [
# url(regex, view, kwargs=None, name=None),
url(正則表達(dá)式, 視圖函數(shù)名, 可選參數(shù), 路由別名),
]
"""

url()函數(shù)中的參數(shù)解釋?zhuān)?/p>

正則表達(dá)式:一個(gè)正則表達(dá)式字符串
views視圖函數(shù):一個(gè)可調(diào)用對(duì)象,通常為一個(gè)視圖函數(shù)或一個(gè)指定視圖函數(shù)路徑的字符串
參數(shù):可選的要傳遞給視圖函數(shù)的默認(rèn)參數(shù)(字典形式)
別名:一個(gè)可選的name參數(shù),用于反向解析
"""

細(xì)說(shuō)url函數(shù)的第一個(gè)參數(shù):

from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]


1568254289925_Django框架.jpg


注意點(diǎn):

urlpatterns列表中的元素按照書(shū)寫(xiě)順序從上往下逐一匹配正則表達(dá)式,一旦匹配成功則不再繼續(xù)。

當(dāng)請(qǐng)求匹配urlpatterns完所有元素后也未匹配成功,就會(huì)向客戶(hù)端返回404.

若要從URL中捕獲一個(gè)值,只需要在 / / 里放置一對(duì)圓括號(hào),并寫(xiě)上對(duì)應(yīng)的正則匹配即可(分組匹配)。

不需要添加一個(gè)前導(dǎo)的反斜杠,因?yàn)槊總€(gè)URL 默認(rèn)前面就會(huì)有反斜杠。例如,應(yīng)該是^articles 而不是 ^/articles。

每個(gè)正則表達(dá)式前面的'r' 是可選的但是建議加上。讓正則字符串中任何字符都不被轉(zhuǎn)義,保留原始。

路由正則表達(dá)式結(jié)尾是否要加 '/' 說(shuō)明:

from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^index/$', views.index), # 結(jié)尾加'/'
url(r'^test$', views.test), # 結(jié)尾不加 '/'
]


例如:

測(cè)試1:訪問(wèn)http://127.0.0.1:8000/index或http://127.0.0.1:8000/index/ 結(jié)果都是成功的,因?yàn)楫?dāng)訪問(wèn)http://127.0.0.1:8000/index時(shí)會(huì)自動(dòng)做301重定向到http://127.0.0.1:8000/index/

測(cè)試2:訪問(wèn)http://127.0.0.1:8000/test是成功的, http://127.0.0.1:8000/test/就會(huì)失敗了

那么到底是什么原因?怎么會(huì)這樣呢?

# 如路由中結(jié)尾有'/' 但請(qǐng)求中的url結(jié)尾沒(méi)有加'/'匹配時(shí)是否在URL中附加尾部斜杠 True添加,F(xiàn)alse不添加

APPEND_SLASH=True # Django的global_settings的默認(rèn)配置

測(cè)試1中:http://127.0.0.1:8000/index寫(xiě)法也能訪問(wèn)成功的原因就是APPEND_SLASH默認(rèn)設(shè)置了為T(mén)rue,但是如果把此配置改為False,那么訪問(wèn) r'^index/$' 路由時(shí)就必須在結(jié)尾的加上'/'。

總結(jié):

由此測(cè)試可以說(shuō)明在定義路由時(shí)結(jié)尾加上 '/ ' 會(huì)讓路由更加靈活。

沒(méi)有命名的正則表達(dá)式組:

# 將加圓括號(hào)的正則表達(dá)式匹配到的內(nèi)容當(dāng)做位置參數(shù)自動(dòng)傳遞給對(duì)應(yīng)的視圖函數(shù)

# 路由層

url(r'^test/(\d+)/',views.test), # 匹配一個(gè)或多個(gè)數(shù)字

# 視圖層

def test(request, num): # num接收到從路由括號(hào)圓括號(hào)內(nèi),相應(yīng)正則表達(dá)式中匹配的值

print(num)

return HttpResponse('test')

有命名的正則表達(dá)式組:

在Python的正則表達(dá)式中,分組命名正則表達(dá)式組的語(yǔ)法是(?Ppattern),其中name是組的名稱(chēng),pattern是要匹配的模式

# 將加圓括號(hào)的正則表達(dá)式匹配到的內(nèi)容當(dāng)做關(guān)鍵字參數(shù)自動(dòng)傳遞給對(duì)應(yīng)的視圖函數(shù)

# 路由層

url(r'^test/(?P\d+)/',views.test), # 匹配一個(gè)或多個(gè)數(shù)字

# 視圖層

def test(request, year): # 此處的形參名一定要和正則組命名一致

print(year)

return HttpResponse('test')

下面是代碼是 使用有命名的正則表達(dá)式組重寫(xiě):

from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/(?P[0-9]{4})/$', views.year_archive),
url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/$', 
views.month_archive),
url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/(?P[0-9]{2})/$', 
views.article_detail),
]


這個(gè)實(shí)現(xiàn)與前面的示例完全相同,只有一個(gè)細(xì)微的差別:捕獲的值作為關(guān)鍵字參數(shù)而不是位置參數(shù)傳遞給視圖函數(shù)。

在實(shí)際應(yīng)用中,使用有命名的正則表達(dá)式組會(huì)更加明晰且不容易產(chǎn)生參數(shù)順序問(wèn)題的錯(cuò)誤 —— 你可以在你的視圖函數(shù)定義中重新安排參數(shù)的順序。 當(dāng)然,這些好處是以簡(jiǎn)潔為代價(jià)的;一些開(kāi)發(fā)人員發(fā)現(xiàn)命名組語(yǔ)法丑陋而且太冗長(zhǎng)。

注意:

無(wú)名正則表達(dá)式組和有名正則表達(dá)式組不能混著用!!!

# 要么都不命名

url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),

# 要命名都要命名

url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/$', views.month_archive),

# 不能這樣混著用,報(bào)錯(cuò)提示缺少必傳位置參數(shù)

url(r'^articles/(?P[0-9]{4})/([0-9]{2})/$', views.month_archive),

正則表達(dá)式組捕獲的參數(shù)都是字符串類(lèi)型:

每個(gè)捕獲的參數(shù)都作為一個(gè)普通的Python 字符串傳遞給視圖,無(wú)論正則表達(dá)式使用的是什么匹配方式。 例如,

url(r'^articles/(?P[0-9]{4})/$', views.year_archive),

傳遞給views.year_archive()的year參數(shù)將是一個(gè)字符串,不是整數(shù),即使[0-9]{4}只匹配整數(shù)字符串

指定視圖參數(shù)的默認(rèn)值:

在這里給大家說(shuō)一個(gè)方便的小技巧是指定視圖參數(shù)的默認(rèn)值。 URLconf 和視圖的示例:

# URLconf
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^blog/$', views.page),
url(r'^blog/page(?P[0-9]+)/$', views.page),
]
# View (in blog/views.py)
def page(request, num="1"):
# 此處省略若干行代碼...


在上面的例子中:

兩個(gè)URL指向同一個(gè)視圖views.page

但是第一個(gè)不會(huì)從URL 中捕獲任何值。 如果第一個(gè)匹配成功,page() 函數(shù)中num將使用默認(rèn)的參數(shù)值"1"。

如果第二個(gè)模式匹配,page() 將使用正則表達(dá)式捕獲的num 值。

通過(guò)上面例子,你發(fā)現(xiàn)了什么呢?

說(shuō)明我們視圖函數(shù)中的普通參數(shù)變?yōu)槟J(rèn)參數(shù)后,可以讓我們的視圖函數(shù)變的更靈活,這樣我們可以讓一個(gè)視圖函數(shù)被多種路由去靈活使用。


推薦了解黑馬程序員課程:

java培訓(xùn)課程

python培訓(xùn)課程

大數(shù)據(jù)培訓(xùn)課程

分享到:
在線(xiàn)咨詢(xún) 我要報(bào)名
和我們?cè)诰€(xiàn)交談!