Django路由層詳解

Django中路由的作用

URL配置(URLconf)就是Django 所支撐的網站的目錄。它的本質是URL與要爲該URL調用的視圖函數之間的映射表;你就是以這種方式告訴Django,對於客戶端發來的某個URL調用哪一段邏輯代碼對應執行

典型例子:

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

路由的基本使用

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
	url(正則表達式, views視圖函數,參數,別名),
]
  • 正則表達式:一個正則表達式字符串
  • views視圖函數:一個可調用對象,通常爲一個視圖函數或一個指定視圖函數路徑的字符串
  • 參數:可選的要傳遞給視圖函數的默認參數(字典形式)
  • 別名:一個可選的name參數
注意:
  • 若要從URL 中捕獲一個值,只需要在它周圍放置一對圓括號。
  • 不需要添加一個前導的反斜槓,因爲每個URL 都有。例如,應該是^articles 而不是 ^/articles。
  • 每個正則表達式前面的’r’ 是可選的但是建議加上。它告訴Python 這個字符串是“原始的”
  • urlpatterns中的元素按照書寫順序從上往下逐一匹配正則表達式,一旦匹配成功則不再繼續
APPEND_SLASH

Django settings.py配置文件中默認沒有 APPEND_SLASH 這個參數,但 Django 默認這個參數爲 APPEND_SLASH = True。 其作用就是自動在網址結尾加’/’。

其效果就是:

我們定義了urls.py

from django.conf.urls import url
from app01 import views

urlpatterns = [
	url(r'^blog/$', views.blog),
]

訪問 http://www.example.com/blog 時,默認將網址自動轉換爲 http://www.example/com/blog/

如果在settings.py中設置了 APPEND_SLASH=False,此時我們再請求 http://www.example.com/blog 時不再向後面自動添加/,就會提示找不到頁面。

路由的分組

無名分組

# 路由層
from django.conf.urls import url
from app01 import views

urlpatterns = [
	url(r'^blog/$', views.blog),
	url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
]

# 視圖層
def year_archive(request, year):
	'''
	year: 接收路由層傳遞過來的參數
	'''
	return HttpResponse('當前是%s年' % year)

上面的示例使用簡單的、沒有命名的正則表達式組(通過圓括號)來捕獲URL 中的值並以位置 參數傳遞給視圖。在更高級的用法中,可以使用命名的正則表達式組來捕獲URL 中的值並以關鍵字 參數傳遞給視圖。

無名分組分出幾個值,視圖函數就要接受幾個值(位置參數形式傳過來的)

有名分組

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

按照有名分組,上面的示例應該這樣寫:

from django.conf.urls import url
from app01 import views

urlpatterns = [
	url(r'^blog/$', views.blog),
	url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
]

有名分組與無名分組在使用上沒有太大差別,只是有名分組對應的視圖函數的形參名字必須和分組名保持一致,也就是說,有名分組會把分出來的參數按照關鍵字參數傳遞給視圖函數,所以一定要保持名字上的一致

在實際應用中,這意味你的URLconf 會更加明晰且不容易產生參數順序問題的錯誤 —— 你可以在你的視圖函數定義中重新安排參數的順序。當然,這些好處是以簡潔爲代價。

注意:有名分組和無名分組不能混合使用

路由分發

一個Django項目裏面有多個app時,不同app的視圖層可能會有名字相同的視圖函數,爲了避免名稱衝突,我們通過路由分發的方式在總路由中進行分發,使每個app在自身內部進行路由的配置

# 導入include
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 匹配順序:匹配app01成功則相應include函數,去到app01文件夾下的urls文件中繼續匹配後續路由
    url(r'^app01/', include('app01.urls')),
	url(r'^app02/', include('app02.urls'))
]
# app01中的urls文件內容
from app01 import views

urlpatterns = [
	url(r'^test/', views.test),
]

如果瀏覽器輸入app01/test/,就會響應到app01下views中的test取執行

反向解析(瞭解)

在視圖函數中重定向的地址如果是寫死的,url地址變更時,需要所有的url都進行修改,比較麻煩,我們可以通過反向解析,動態獲取url的地址

# 路由層
from django.conf.urls import url
from app01 import views

urlpatterns = [
	url(r'^admin/', admin.site.urls),
	url(r'^test/$', views.test, name='test')
]
# 視圖層
from django.shortcuts import reverse

def re_url():
	url=reverse('test(url地址的別名)')
	# 如果做了分組(意味着需要接受參數)
	url=reverse('test(url地址的別名)',args=[],kwargs={})
	return redirect(url)
{# django模板層 #}
{% url 'url地址的別名'%}
# 如果做了分組(意味着需要接受參數)
{% url 'url地址的別名' 參數1 參數2 ... 參數n %}

這樣,即使路由層中的路由更改了,我們也可以不用修改視圖層或模板層的路由地址,即便我們不應該去修改路由層中的路由。

名稱空間

路由分發時,可以指定名稱空間:

# 導入include
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app01/', include('app01.urls', namespace='app01')),
	url(r'^app02/', include('app02.urls', namespace='app02'))
]

名稱空間可以在視圖層進行反向解析使用
不建議使用名稱空間

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章