Python全棧工程師學習筆記 | Django的URL路由

尋夢新聞LINE@每日推播熱門推薦文章,趣聞不漏接❤️

加入LINE好友

Python全棧工程師學習筆記 | Django的URL路由 科技 第1張

一個乾淨優雅的URL方案是高質量Web應用程序中的一個重要細節。

Django可以讓你自己設計URL,無論你想要什麼,沒有框架限制。

要為應用程序設計URL,您可以非正式地創建一個名為**URLconf**(URL配置)的Python模塊。

這個模塊是純Python代碼,是一個簡單的Python模式(簡單的正則表達式)到Python函數(您的視圖)之間的映射。

這個模塊是純Python代碼,是一個簡單的Python模式(簡單的正則表達式)到Python函數(您的視圖)之間的映射。

Django是如何處理一個請求?

當用戶從Django的站點請求頁面時,系統遵循以下步驟來執行的Python代碼:

1. 首先Django確定要使用的根URLconf模塊,通過ROOT_URLCONF來設置,具體在settings.py配置文件中。但是如果傳入 HttpRequest對象具有urlconf 屬性(由中間件設置),則其值將用於替換ROOT_URLCONF設置。

2. Django加載該Python模塊並查找該變量 urlpatterns。這應該是一個Python的django.conf.urls.url()實例列表。

3.Django按順序運行每個URL模式,並在匹配所請求的URL的第一個URL中停止。

4.一旦正則表達式匹配,Django將導入並調用給定的視圖,這是一個簡單的Python函數(或基於類的視圖)。該視圖通過以下參數傳遞:

    一個實例HttpRequest。

    如果匹配的正則表達式沒有返回任何命名組,那麼來自正則表達式的匹配將作為位置參數提供。

    關鍵字參數由正則表達式匹配的任何命名組組成,由可選kwargs參數中指定的任何參數覆蓋 django.conf.urls.url()。

5.如果沒有正則表達式匹配,或者在此過程中的任何一點出現異常,Django將調用適當的錯誤處理視圖。

示例

以下是一個URLconf示例:

fromdjango.conf.urlsimporturlfrom.importviewsurlpatterns=[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),]

說明:

  • 要從URL捕獲一個值,只需將其括起來。

  • 沒有必要添加一個主要的斜杠,因為每個URL都有。例如^articles,不是^/articles。

  • 正則中的’r’正面的每個正則表達式字符串的中是可選的,但推薦使用。它告訴Python一個字符串是「raw」 – 字符串中沒有任何內容應該被轉義。請參閱Dive Into Python的解釋。

示例請求:

  • /articles/2005/03/將匹配列表中的第三個條目。Django會調用該函數 。views.month_archive(request, ‘2005’, ’03’)

  • /articles/2005/3/ 不符合任何網址格式,因為列表中的第三個條目需要兩個數字的月份。

  • /articles/2003/將匹配列表中的第一個模式,而不是第二個模式,因為模式是按順序測試的,第一個模式是第一個測試通過。隨意利用這些命令插入特殊情況。在這里,Django會調用該函數 views.special_case_2003(request)

  • /articles/2003 將不匹配任何這些模式,因為每個模式要求URL以斜杠結尾。

  • /articles/2003/03/03/將匹配最終模式。Django會調用該函數。views.article_detail(request, ‘2003’, ’03’, ’03’)

注意:每個捕獲的參數都作為純Python字符串發送到視圖,無論正則表達式的匹配是什麼,即使[0-9]{4}只會匹配整數字符串。

通過瀏覽器訪問服務

注意:url路由,由上而下 進行匹配,如果在上面就匹配成功,則不會向下匹配

通過瀏覽器訪問服務127.0.0.1:8000/abc==>rooturl(根路由)==>加載子路由(myweb/urls.py)==>正則匹配訪問的路徑(path)=-=>視圖函數(views.index)==>views.pyindex()響應內容

命名組

  • 上述使用為簡單實例,屬於正則表達式非命名組(通過括號)捕獲URL定位,並將它們作為位置參數傳遞給視圖。

  • 在更高級的使用中,我們可以使用正則表達式命名組來捕獲URL定位,並將它們作為關鍵字 參數傳遞給視圖。

  • 在Python正則表達式中,正則表達式命名組的語法是(?P<name>pattern),其中命名組中的命名就是name,並且 pattern是某些匹配的模式。

實例

fromdjango.conf.urlsimporturlfrom.importviewsurlpatterns=[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),]

這完成了與上一個例子完全相同的事情,有一個微妙的區別:捕獲的值被傳遞到視圖函數作為關鍵字參數,而不是位置參數。

例如:

  • 請求/articles/2005/03/調用函數 ,。views.month_archive(request, year=’2005′, month=’03’) 而不是 views.month_archive(request, ‘2005’, ’03’)

  • 請求/articles/2003/03/03/調用函數 。views.article_detail(request, year=’2003′, month=’03’, day=’03’)

  • 在實踐中,這意味著您的URLconfs稍微更明確,更不容易出現參數命令錯誤 – 您可以重新排序視圖的函數定義中的參數。當然,這些好處是以簡潔為代價的; 一些開發人員發現命名組語法醜陋而且太冗長。

URLconf的搜尋

URLconf將根據所請求的URL進行搜尋,作為普通的Python字符串。這不包括GET或POST參數或域名。

例如:

  • 在請求中https://www.example.com/myapp/,URLconf將尋找myapp/。

  • 在請求中https://www.example.com/myapp/?page=3,URLconf將會查找myapp/。

URLconf不查看請求方法。換句話說,所有的請求方法(GET,POST,HEAD等)都將被路由到相同的URL功能。

指定用於視圖參數的默認值

一個方便的技巧是為您的視圖參數指定默認參數。下面是一個URLconf和view的例子.

在下面的示例中,兩個URL模式指向相同的視圖views.page- 但是第一個模式不會從URL捕獲任何內容。

如果第一個模式匹配,該page()函數將使用它的默認參數num,”1″。

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

#URLconffromdjango.conf.urlsimporturlfrom.importviewsurlpatterns=[url(r'^blog/$',views.page),url(r'^blog/page(?P<num>[0-9]+)/$',views.page),]#View(inblog/views.py)defpage(request,num="1"):#Outputtheappropriatepageofblogentries,accordingtonum....

錯誤處理

當Django找不到與請求的URL匹配的正則表達式時,或者異常引發時,Django將調用錯誤處理視圖。

用於這些情況的視圖由四個變量指定。它們的默認值對於大多數項目都是足夠的,但通過覆蓋其默認值可以進一步定制。

有關詳細信息,請參閱自定義錯誤視圖的文檔。

這樣的值可以在你的根URLconf中設置。在任何其他URLconf中設置這些變量將不起作用。

值必須是可調用的,或者代表視圖的完整的Python導入路徑的字符串,應該被調用來處理手頭的錯誤條件。

變量是:

  • handler400- 見django.conf.urls.handler400。

  • handler403- 見django.conf.urls.handler403。

  • handler404- 見django.conf.urls.handler404。

  • handler500- 見django.conf.urls.handler500。

關於404錯誤

  • 404的錯誤頁面,在模板目錄中創建一個404.html的頁面,

  • 在配置文件中settings.py DEBUG=False

  • 在出現404的情況時,自動尋找404頁面。

  • 也可以在視圖函數中 手動報出404錯誤,帶提醒信息

在視圖函數中也可以指定返回一個404

注意Http404需要在django.http的模塊中引入#響應404raiseHttp404('納尼a')

在模板中 404.html

<!DOCTYPEhtml><html><head><title>404</title></head><body><center><h2>404notfound</h2><h3>{{exception}}</h3></center></body></html>

包括其他的URLconf

在任何時候,urlpatterns都可以「包含」其他URLconf模塊。這實質上是將一組網址「植根於」其他網址之下。

例如,下面是Django網站本身的URLconf的摘錄。它包含許多其他URLconf:

fromdjango.conf.urlsimportinclude,urlurlpatterns=[#...snip...url(r'^community/',include('django_website.aggregator.urls')),url(r'^contact/',include('django_website.contact.urls')),#...snip...]

請注意,此示例中的正則表達式沒有$(字符串尾匹配字符),但包含尾部斜線。

每當Django遇到include()(django.conf.urls.include())時,它會截斷與該點匹配的URL的任何部分,並將剩餘的字符串發送到包含的URLconf以供進一步處理。

URL的反向解析

如果在視圖、模板中使用硬編碼的鏈接,在urlconf發生改變時,維護是一件非常麻煩的事情。

  • 解決:在做鏈接時,通過指向urlconf的名稱,動態生成鏈接地址

  • 視圖:使用django.core.urlresolvers.reverse()函數

  • 模板:使用url模板標籤

示例

在URLconf中

fromdjango.conf.urlsimportinclude,urlurlpatterns=[#...snip...url(r'^community/',include('django_website.aggregator.urls')),url(r'^contact/',include('django_website.contact.urls')),#...snip...]

您可以使用以下模板代碼獲取這些:

<ahref="{%url'news-year-archive'2012%}">2012Archive</a>{#Orwiththeyearinatemplatecontextvariable:#}<ul>{%foryearvarinyear_list%}<li><ahref="{%url'news-year-archive'yearvar%}">{{yearvar}}Archive</a></li>{%endfor%}</ul>

在Python代碼中:

fromdjango.urlsimportreversefromdjango.httpimportHttpResponseRedirectdefredirect_to_year(request):#...year=2006#...returnHttpResponseRedirect(reverse('news-year-archive',args=(year,)))

或簡寫

fromdjango.shortcutsimportredirectfromdjango.core.urlresolversimportreversedefindex(request):year=2006returnredirect(reverse('ews-year-archive',args=(year,)))

福利

掃碼添加小助手微信,回復:1,入群獲取Python電子書(附代碼~~)

Python全棧工程師學習筆記 | Django的URL路由 科技 第2張

推薦閱讀:

Python全棧工程師學習筆記 | Django的URL路由 科技 第3張

About 尋夢園
尋夢園是台灣最大的聊天室及交友社群網站。 致力於發展能夠讓會員們彼此互動、盡情分享自我的平台。 擁有數百間不同的聊天室 ,讓您隨時隨地都能找到志同道合的好友!