教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

Django路由配置方法和注意問題詳解

更新時間:2021年03月10日16時59分 來源:傳智教育 瀏覽次數(shù):

好口碑IT培訓(xùn)

Django中路由的作用:

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

路由基本的配置:

from django.conf.urls import url

# urlpatterns必須是一個由url()實例組成的Python列表
urlpatterns = [
  	# url(regex, view, kwargs=None, name=None),
    url(正則表達式, 視圖函數(shù)名, 可選參數(shù), 路由別名),
]

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

細說url函數(shù)的第一個參數(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),
]

==注意點:==

  1. urlpatterns列表中的元素按照書寫順序從上往下逐一匹配正則表達式,一旦匹配成功則不再繼續(xù)。
  2. 當(dāng)請求匹配urlpatterns完所有元素后也未匹配成功,就會向客戶端返回404.
  3. 若要從URL中捕獲一個值,只需要在 ==/  /== 里放置一對圓括號,并寫上對應(yīng)的正則匹配即可(分組匹配)。
  4. 不需要添加一個前導(dǎo)的反斜杠,因為每個URL 默認前面就會有反斜杠。例如,應(yīng)該是^articles 而不是 ^/articles。
  5. 每個正則表達式前面的'r' 是可選的但是建議加上。讓正則字符串中任何字符都不被轉(zhuǎn)義,保留原始。

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

from django.conf.urls import url
from app01 import views

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

例如:

    測試1:訪問http://127.0.0.1:8000/indexhttp://127.0.0.1:8000/index/ 結(jié)果都是成功的,因為當(dāng)訪問http://127.0.0.1:8000/index時會自動做301重定向到http://127.0.0.1:8000/index/

URL01

    測試2:訪問http://127.0.0.1:8000/test是成功的, http://127.0.0.1:8000/test/就會失敗了

URL02


那么到底是什么原因?怎么會這樣呢?

# 如路由中結(jié)尾有'/' 但請求中的url結(jié)尾沒有加'/'匹配時是否在URL中附加尾部斜杠 True添加,F(xiàn)alse不添加
APPEND_SLASH=True  # Django的global_settings的默認配置

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

總結(jié):

由此測試可以說明在定義路由時結(jié)尾加上 '/ ' 會讓路由更加靈活。

沒有命名的正則表達式組:

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

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

# 視圖層
def test(request, num):   # num接收到從路由括號圓括號內(nèi),相應(yīng)正則表達式中匹配的值
    print(num)
    return HttpResponse('test')

有命名的正則表達式組:

    在Python的正則表達式中,分組命名正則表達式組的語法是(?P<name>pattern),其中name是組的名稱,pattern是要匹配的模式

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

# 路由層
url(r'^test/(?P<year>\d+)/',views.test),  # 匹配一個或多個數(shù)字

# 視圖層
def test(request, year):  # 此處的形參名一定要和正則組命名一致
    print(year)
    return HttpResponse('test')

下面是代碼是 使用有命名的正則表達式組重寫:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

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

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

注意:

  無名正則表達式組和有名正則表達式組不能混著用?。?!# 要么都不命名

url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), 
# 要命名都要命名
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), 
# 不能這樣混著用,報錯提示缺少必傳位置參數(shù)
url(r'^articles/(?P<year>[0-9]{4})/([0-9]{2})/$', views.month_archive),

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

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

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

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

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

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

# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# View (in blog/views.py)
def page(request, num="1"):
    # 此處省略若干行代碼...

在上面的例子中:

    兩個URL指向同一個視圖views.page

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

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

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

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

猜你喜歡

什么是Python?最全的python百科

學(xué)會python可以做什么?這些好處你想象不到

Django海量數(shù)據(jù)集分頁優(yōu)化方法

使用Django中間件的六種方法

Python+數(shù)據(jù)分析課程

0 分享到:
和我們在線交談!