Django4.0 URL調度器-使用正則表達式

2022-03-16 17:42 更新

如果路徑和轉化器語法不能很好的定義你的 URL 模式,你可以可以使用正則表達式。如果要這樣做,請使用 ?re_path()? 而不是 ?path()? 。

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

這里是先前 ?URLconf ?的一些例子,現(xiàn)在用正則表達式重寫一下:

from django.urls import path, re_path

from . import views

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    re_path(r'^articles/(?P<year>[0-9]{4})/, views.year_archive), 
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/, views.month_archive), 
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/, views.article_detail),
 ]

這實現(xiàn)了與前面示例大致相同的功能,除了:

  • 將要匹配的 URLs 將稍受限制。比如,10000 年將不在匹配,因為 year 被限制長度為4。
  • 無論正則表達式進行哪種匹配,每個捕獲的參數(shù)都作為字符串發(fā)送到視圖。

當從使用 ?path()? 切換到 ?re_path()? (反之亦然),要特別注意,視圖參數(shù)類型可能發(fā)生變化,你可能需要調整你的視圖。

使用未命名的正則表達式組

還有命名組語法,例如 ?(?P<year>[0-9]{4})? ,你也可以使用更短的未命名組,例如 ?([0-9]{4})? 。
不是特別推薦這個用法,因為它會更容易在匹配的預期含義和視圖參數(shù)之間引發(fā)錯誤。

在任何情況下,推薦在給定的正則表達式里只使用一個樣式。當混雜兩種樣式時,任何未命名的組都會被忽略,而且只有命名的組才會傳遞給視圖函數(shù)。

嵌套參數(shù)

正則表達式允許嵌套參數(shù),Django 將處理它們并傳遞給視圖。當轉換時,Django 將試著填充給所有外部捕捉參數(shù),忽略任何嵌套捕捉參數(shù)??紤]下面可選的帶有頁面參數(shù)的 URL 模式:

from django.urls import re_path

urlpatterns = [
    re_path(r'^blog/(page-(\d+)/)?, blog_articles),                  # bad
    re_path(r'^comments/(?:page-(?P<page_number>\d+)/)?, comments),  # good
]

兩個模式使用嵌套參數(shù),并處理:例如, ?blog/page-2/? 將匹配給 ?blog_articles? 并帶有2個參數(shù):?page-2/? 和 ??。第二個模式為 ?comments ?匹配 ?comments/page-2/? 并帶有設置為2的關鍵參數(shù) ?page_number ?。這個案例里的外部參數(shù)是一個非捕捉參數(shù) (?:...) 。

?blog_articles ?視圖需要反轉最外層捕捉的參數(shù),?page-2/? 在這里不需要參數(shù),而 ?comments可以在沒有參數(shù)或 ?page_number值的情況下反轉。

嵌套捕捉參數(shù)在視圖參數(shù)和 URL 直接創(chuàng)建一個強耦合,如 ?blog_articles所示:視圖接收部分 URL (?page-2/?) 而不只是視圖要的值。當反轉時這種耦合更明顯,因為反轉視圖我們需要傳遞一段 URL 而不是 ?page number?。

根據(jù)經驗,只有當正則表達式需要一個參數(shù)但視圖忽略它時,才捕捉該視圖需要的值并使用非捕捉參數(shù)。


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號