1. 程式人生 > >Django2.0路由層-URLconf

Django2.0路由層-URLconf

不能 開頭 功能 匹配模式 tail 順序 git 整數 IE

DJango2.0路由層-URLconf

  • URL配置(URLconf)就像Django 所支撐網站的目錄樹。
  • 它的本質是URL與要為該URL調用的視圖函數之間的映射表;
    • 對於客戶端發來的某個URL調用哪一段邏輯代碼對應執行。
    • 一般來說,一個路徑對應一個視圖函數。它並非一一對應!
    • 多個路徑可以對應一個視圖函數,但是一個路徑,不能對應多個視圖函數。

urlpatterns

urls.py中默認就有urlpatterns,可以把它看作一個存放了映射關系的列表。
django2.0中常用的是path()方法,還可以使用re_path()方法來兼容1.x版本中的url()方法。

  • 用法大致都是一樣的,這些方法主要接收4個參數:
    • 2個是必須的:regext
      view
    • 2個是可選的:kwargsname
  • regex(正則表達式):
    • regex是正則表達式的通用縮寫,可以用正則來匹配url地址。
    • 用戶請求url地址,urls.py對urlpatterns列表中的每一項條目從頭開始進行逐一對比,一旦遇到匹配項,立即執行該條目映射的視圖函數或下級路由,其後的條目將不再繼續匹配。
    • 所以,url路由的編寫順序非常重要!
    • regex不會去匹配GET或POST參數或域名。
  • view(視圖函數):
    • view指的是處理當前url請求的視圖函數。
    • 當正則表達式匹配到某個條目時,自動將封裝的HttpRequest對象作為第一個參數,正則表達式“捕獲”到的值作為第二個參數,傳遞給該條目指定的視圖view。
    • 如果是簡單捕獲,那麽捕獲值將作為一個位置參數進行傳遞,如果是命名捕獲,那麽將作為關鍵字參數進行傳遞。
  • kwargs:
    • 任意數量的關鍵字參數可以作為一個字典傳遞給目標視圖。
  • name(別名):
    • 對你的URL進行命名,讓你能夠在Django的任意處,尤其是模板內顯式地引用它。
    • 這是一個非常強大的功能,相當於給URL取了個全局變量名,不會將url匹配地址寫死。

實例

from django.contrib import admin
from django.urls import path

from . import views

urlpatterns = [
    path(‘articles/2018/‘, views.special_case_2018),
    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。
    • 默認情況下,捕獲到的結果保存為字符串類型,不包含/這個特殊字符;
  • 匹配模式的開頭可以不添加/,默認情況下,每個url都帶一個最前面的/,共有的部分,不用特別寫了。

匹配例子:

  • /articles/2017/06/ 將匹配第三條,並調用views.month_archive(request, year=2017, month=6);
  • /articles/2018/匹配第一條,並調用views.special_case_2018(request);
  • /articles/2018將一條都匹配不上,因為它最後少了一個斜杠,而列表中的所有模式中都以斜杠結尾;
  • /articles/2016/05/building-a-django-site/ 將匹配最後一個,並調用views.article_detail(request, year=2016, month=5, slug="building-a-django-site"。

path轉換器

默認情況下,Django內置下面的路徑轉換器:

  • str:匹配任何非空字符串,但不含斜杠/,默認使用;
  • int:匹配0和正整數,返回一個int類型;
  • slug:可理解為註釋、後綴、附屬等概念,是url在最後的一部分解釋性字符。
    • 該轉換器匹配任何ASCII字符以及連接符和下劃線;
  • uuid:匹配一個uuid格式的對象。為了防止沖突,規定必須使用破折號,所有字母必須小寫。
    • 0863561d3-9527-633c-b9b6-8a032e1565f0。返回一個UUID對象;
  • path:匹配任何非空字符串,重點是可以包含路徑分隔符/
    • 這個轉換器可以幫助你匹配整個url而不是一段一段的url字符串。

自定義path轉換器

寫一個類,並包含下面的成員和屬性:

  • 類屬性regex:一個字符串形式的正則表達式屬性;
  • to_python(self, value) 方法:
    • 用於將匹配到的字符串轉換為你想要的那個數據類型,並傳遞給視圖函數。
    • 如果轉換失敗,它必須彈出ValueError異常;
  • to_url(self, value)方法:
    • 將Python數據類型轉換為一段url的方法,to_python方法的反向操作。

例如,新建一個converters.py文件,與urlconf同目錄,寫個下面的類:

class FourDigitYearConverter:
    regex = ‘[0-9]{4}‘

def to_python(self, value):
    return int(value)

def to_url(self, value):
    return ‘%04d‘ % value

寫完類後,在URLconf 中註冊,並使用它,如下所示,註冊了一個yyyy:

from django.urls import register_converter, path

from . import converters, views

register_converter(converters.FourDigitYearConverter, ‘yyyy‘)

urlpatterns = [
    path(‘articles/2018/‘, views.special_case_2018),
    path(‘articles/<yyyy:year>/‘, views.year_archive),
    ...
]

使用正則表達式

Django2.0的url雖然改‘配置’了,但它依然向老版本兼容。
而這個兼容的辦法,就是用re_path()方法代替path()方法。
re_path()方法在骨子裏,根本就是以前的url()方法,只不過導入的位置變了。

下面是一個例子,對比一下Django1.11時代的語法,有什麽太大的差別?

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),
]
  • 與path()方法不同的在於兩點:
    • year中匹配不到10000等非四位數字,這是正則表達式決定的
    • 傳遞給視圖的所有參數都是字符串類型。
      • 不像path()方法中可以指定轉換成某種類型。在視圖中接收參數時一定要小心。

參考引用:
http://www.liujiangblog.com/blog/17/

Django2.0路由層-URLconf