在當代的web應用中,清晰優雅的URL非常重要,在Django架構中,你可以随心所欲的設計你的URL,不用擔心架構的限制。
概覽
為了給一個app設計URL,你建立一個Python子產品叫做
URLConf
,這個子產品是純Python代碼并且用于于映射URL路徑和Python的功能或視圖。
這個映射關系可以寫的比較短,它也可以引用其它的映射,并且由于它是純代碼,所有它可以動态的建構。
Django如何處理請求
當使用者請求一個由Django建構的網站,下面是Django的處理方式來決定執行那一部分的Python代碼
- Django找到root(根)URLconf子產品,根子產品一般與項目同名的目錄下,當然這個可以在ROOT_URLCONF配置中設定,但是如果請求的HttpRequest對象由urlconf屬性(通過中間件設定),它的值将會用于替換 ROOT_URLCONF的設定。
- Django加載python的子產品,然後朝找urlpattern變量,這個應該是一系列的
或者django.urls.path()
的執行個體django.urls.re_path()
- Django周遊URL樣式,在第一個比對請求的時候停止周遊。
- 一旦其中的一個URL樣式被比對了,django導入和調用提供的視圖,一般是Python的函數,視圖将會傳遞下面的參數
- 一個HttpRequest的執行個體
- 如果比對的URL樣式傳回無命名的組,那麼從正規表達式中比對的部分将作為對應位置的參數
- 關鍵參數由比對路徑表達式的命名部分組成,由指定的參數覆寫.
- 如果沒有URL比對,或者抛出了異常,Django将會調用一個合适的錯誤處理視圖。
案例
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]
注意:
- 想要從URL中捕捉值,使用尖括号
- 捕捉值可以包含轉換後的類型,例如<int:name>捕捉的是整數,如果轉換器沒有包括進來,任何字元串除了
也可以比對/
- 在開頭部分不需要天劍
,因為它是/
,不是articles
/articles
請求映射:
- 請求/article/2005/03/ 對應清單中的第三個條目,django會調用views.month_archive(request,year=2005,month=3)
- 請求 /article/2003/ 對應清單中的第一個,因為django找到符号規則的就停下來了。調用views.special_case_2003(request)函數
- /article/2003 不會比對任何一個條目,因為每一個條目後面都有一個
/
- /articles/2003/03/building-a-django-site/ 比對最後一個條目,調用views.article_detail(request, year=2003, month=3, slug="building-a-django-site") 函數
Path Converter(路徑轉換器)
下面這些是預設可用的轉換器
- str: 比對非空字元串,除了
。這個是預設的轉換器/
- int 比對0或者任何正整數
- slug 比對ASCII租車的字元串,加上
和-
。例如_
也可以today_is-2018-10
- path 比對非空的字元串,包含
,這個可以比對一個完整的URL,而不僅僅是路徑中的一個片段(str)/
當然也可以注冊自己的轉換器,也不麻煩,可以參考官方文檔
使用正規表達式
如果路徑轉換器的文法不夠高效來定義你的URL樣式,你可以使用正規表達式,這時使用
re_path
,而不是
path
正規表達式的文法為:
(?P<name>pattern) ,name是組名,pattern是要比對的樣式
看下面的例子,這樣的表達實作了和剛才使用轉換器同樣的功能。
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),
]
額外
- URLconf子產品隻是用來比對路徑,并不處理請求方法,像GET,POST,PUT等不同類型的請求也會路由到同一個Python函數中。
- 使用include可以引入其他的url子產品。
最後
以上的基本能滿足初步的開發,先暫時到這裡。