Django的路由系統

小小封發表於2019-04-15

Django的路由系統

URL配置(URLconf)就像Django 所支撐網站的目錄。它的本質是URL與要為該URL呼叫的檢視函式之間的對映表。

你就是以這種方式告訴Django,對於這個URL呼叫這段程式碼,對於那個URL呼叫那段程式碼。

URLconf配置

基本格式

from django.conf.urls import url

urlpatterns = [
     url(正規表示式, views檢視函式,引數,別名),
]
複製程式碼

注意:Django2.0版本中的路由系統已經替換成下面的寫法(官方文件):

from django.urls import path

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),
]
複製程式碼

引數說明

  • 正規表示式:一個正規表示式字串
  • views檢視函式:一個可呼叫物件,通常為一個檢視函式或一個指定檢視函式路徑的字串
  • 引數:可選的要傳遞給檢視函式的預設引數(字典形式)
  • 別名:一個可選的name引數

正規表示式詳解

基本配置

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),
]
複製程式碼

注意事項

  • 路由一旦匹配就不再走下面的路由匹配關係了
  • 若要從URL中捕獲一個值,只需要在它周圍放置一對圓括號(分組匹配)。
  • 不需要新增一個前導的反斜槓,因為每個URL 都有。例如,應該是^articles而不是^/articles。
  • 每個正規表示式前面的'r'是可選的但是建議加上。
  • 路由增加首頁的方式 url(r'^$',views.home)
  • 路由增加尾頁的方式(當所有的路徑都匹配不上時,給我返回404提示資訊) url(r'',views.error)

補充說明

是否開啟URL訪問地址後面不為/跳轉至帶有/的路徑的配置項 APPEND_SLASH=True

Django settings.py配置檔案中預設沒有 APPEND_SLASH 這個引數,但 Django 預設這個引數為 APPEND_SLASH = True。 其作用就是自動在網址結尾加'/'。

分組命名匹配

上面的示例使用簡單的正規表示式分組匹配(通過圓括號)來捕獲URL中的值並以位置引數形式傳遞給檢視。

在更高階的用法中,可以使用分組命名匹配的正規表示式組來捕獲URL中的值並以關鍵字引數形式傳遞給檢視。

無名分組

url(r'^test/([0-9]{4})/',views.test)

會將加了括號的正規表示式匹配的內容當做位置引數傳遞給後面的檢視函式

有名分組 url(r'^test/(?P<year>\d+)/',views.test)

會將加了括號的正規表示式匹配的內容當做關鍵字引數傳遞給後面的檢視函式

關鍵字就是尖括號裡面的名字(year)

注意事項

  • 有名分組和無名不能混合使用!!!
  • 只要不混著用,有名分組和無名分組支援多個相同型別的傳參

URLconf匹配的位置

URLconf 在請求的URL 上查詢,將它當做一個普通的Python 字串。不包括GET和POST引數以及域名。

例如,www.example.com/myapp/ 請求中,URLconf 將查詢myapp/。

在http://www.example.com/myapp/?page=3 請求中,URLconf 仍將查詢myapp/。

URLconf 不檢查請求的方法。換句話講,所有的請求方法 —— 同一個URL的POST、GET、HEAD等等 —— 都將路由到相同的函式。

捕獲的引數永遠都是字串

每個在URLconf中捕獲的引數都作為一個普通的Python字串傳遞給檢視,無論正規表示式使用的是什麼匹配方式

反向解析

簡單來說就是可以給我們的URL匹配規則起個名字,一個URL匹配模式起一個名字。

這樣我們以後就不需要寫死URL程式碼了,只需要通過名字來呼叫當前的URL。

前端反向解析
{% url 'add' %}  # {% url'放urls.py中路由與檢視函式的name的值' %} 

後端反向解析
from django.shortcuts import reverse

url(r'^testadd123/$',views.testadd,name='add')

res = reverse('add')
複製程式碼

無名分組的反向解析

前端反向解析
	{% url 'add' 1 %}  # {% url '放urls.py中路由與檢視函式的name的值' %} 
	
後端反向解析
	from django.shortcuts import reverse
	
	url(r'^testadd123/(\d+)/$',views.testadd,name='add')
	
	res = reverse('add',args=(1,))
複製程式碼

有名分組的反向解析

前端反向解析
	{% url 'add' 1 %}  # {% url '放urls.py中路由與檢視函式的name的值' %}   推薦你用這種
	
	<a href="{% url 'add' year=1 %}">999</a>
後端反向解析
	res = reverse('add',args=(1,))  # 推薦你用這種
	
	res = reverse('add',kwargs={'year':1})
複製程式碼

注意: 當命名你的URL 模式時,請確保使用的名稱不會與其它應用中名稱衝突。如果你的URL 模式叫做comment,而另外一個應用中也有一個同樣的名稱,當你在模板中使用這個名稱的時候不能保證將插入哪個URL。

在URL 名稱中加上一個字首,比如應用的名稱,將減少衝突的可能。我們建議使用myapp-comment 而不是comment。

名稱空間模式

在不同的APP使用相同的URL名稱,如果不區分,會導致路由解析錯誤,而URL的名稱空間模式也可以讓你唯一反轉命名的URL。

語法

'名稱空間名稱:URL名稱'

django2.0版的path

django2.0的re_path和1.0的url一樣

path轉化器

文件原文是Path converters,暫且翻譯為轉化器。

Django預設支援以下5個轉化器:

str,匹配除了路徑分隔符(/)之外的非空字串,這是預設的形式
int,匹配正整數,包含0。
slug,匹配字母、數字以及橫槓、下劃線組成的字串。
uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path,匹配任何非空字串,包含了路徑分隔符(/)(不能用?)
複製程式碼

註冊自定義轉化器

對於一些複雜或者複用的需要,可以定義自己的轉化器。轉化器是一個類或介面,它的要求有三點:

  • regex 類屬性,字串型別
  • to_python(self, value) 方法,value是由類屬性 regex 所匹配到的字串,返回具體的Python變數值,以供Django傳遞到對應的檢視函式中。
  • to_url(self, value) 方法,和 to_python - 相反,value是一個具體的Python變數值,返回其字串,通常用於url反向引用。 例子:
需要三步走戰略
# 自定義轉換器
class FourDigitYearConverter:
	regex = '[0-9]{4}'
	def to_python(self, value):
		return int(value)
	def to_url(self, value):
		return '%04d' % value
register_converter(FourDigitYearConverter, 'yyyy')

urlpatterns = [
	path('admin/', admin.site.urls),
	# path('index/<int:id>/',index ),
	# path('index/<str:id>/',index ),
	path('login/<yyyy:name>/',index)

]
複製程式碼

相關文章