1. 程式人生 > 其它 >Django 3.Django框架 - 路由詳解

Django 3.Django框架 - 路由詳解

Django框架 - 路由詳解

Django允許你自由地設計你的 URL,不受框架束縛
為了給一個應用設計 URL,你需要建立一個 Python 模組,通常被稱為 URLconf(URL配置)
這個模組是純粹的 Python 程式碼,包含 URL 模式(簡單的正則表示式)到 Python 函式(檢視函式)的簡單對映


Django 如何處理一個請求

當一個使用者請求 Django 站點的一個頁面,下面是 Django 系統決定執行哪個 Python 程式碼使用的演算法:

  1. Django 確定使用根 URLconf 模組。通常,這是 ROOT_URLCONF 設定的值,但如果傳入 HttpRequest
    物件擁有 urlconf 屬性(通過中介軟體設定),它的值將被用來代替 ROOT_URLCONF 設定。
  2. Django 載入該 Python 模組並尋找可用的 urlpatterns 。它是 django.urls.path() 和(或) django.urls.re_path() 例項的序列(sequence)。
  3. Django 會按順序遍歷每個 URL 模式,然後會在所請求的URL匹配到第一個模式後停止,並與 path_info 匹配。
  4. 一旦有 URL 匹配成功,Djagno 匯入並呼叫相關的檢視,這個檢視是一個Python 函式(或基於類的檢視 class-based view)。檢視會獲得如下引數:
    • 一個
      HttpRequest
      例項。
    • 如果匹配的 URL 包含未命名組,那麼來自正則表示式中的匹配項將作為位置引數提供。
    • 關鍵字引數由路徑表示式匹配的任何命名部分組成,並由 django.urls.path()django.urls.re_path() 的可選 kwargs 引數中指定的任何引數覆蓋。
  5. 如果沒有 URL 被匹配,或者匹配過程中出現了異常,Django 會呼叫一個適當的錯誤處理檢視。參加下面的錯誤處理( Error handling )。

Django框架中的路由定義方式

  • django.urls.path()
  • django.urls.re_path()
    區別:
    path() 定義字串為URL規則
    re_path() 可以是字串和正則的組合
path('abc/',views.ABC),
re_path(r'^\w{3}/$' ,views.DDD),

# '^\w{3}/$' 表示由 三位 字母、數字、下劃線 組成的 以 / 結尾 

Django框架中路由的引數捕獲

  • path()
  • re_path()
    使用以上方法可以捕獲 URL 中的一部分內容作為檢視函式的關鍵字引數進行傳遞

path() < 型別 : 引數名 >

# 路由中可以使用 <型別:引數名> 的方式來捕獲 URL 中的一部分作為引數使用
path('arts/<int:year>/<int:month>/', views.month_archive),

# 路由中如果定義了引數,那麼對應的檢視函式中也必須定義,並且引數名要一致
def month_archive(request,year,month):
    return HttpResponse(f'month_archive:{year},{month}')

re_path() (?P< 引數名 > 引數規則)

# 路由中可以使用 (?P<引數名>引數規則) 來捕獲 URL 中的引數
re_path(r'name/(?P<NAME>\w{2,8})/p/(?P<post>\d{6})',views.getnamepost),

def getnamepost(request,NAME,post):
    return HttpResponse(f'getnamepost:{NAME},{post}')

# 非命名引數捕獲,對應的檢視函式中只要有形參就可以傳遞
re_path(r'(\w{2,8})/p/(\d{6})',views.getnp),

def getnp(request,n,p):
    return HttpResponse(f'getnp:{n},{p}')

Django路由的URL反向解析

假如有這樣一個 URL 的規則是解析到顯示getpost的檢視的對映

# 路由 urls.py
path('getpost/<int:id>/', views.getpost),	

# 檢視 views.py
def getpost(request,id):
    # 把getpost中的內容解析到模板中
    return HttpResponse(f'{id}號:這裡是{id}號')

那麼在需要定義連結地址的地方,如html的a連結中,可以直接用硬編碼的方式定義連結

<!-- URL反向解析.html -->
<a href="/getpost/5/">URL - 硬編碼</a>

但是假如 URL 路由規則改變,那麼對應的連結就會失效,所以不推薦使用硬編碼的方式定義連結

Django的路由可以設定 URL 反向解析來解決以上問題

定義路由規則時,只要給定義的路由設定 name 關鍵字引數,即路由名字

# 指定路由的名字,在使用時通過路由名動態解析路由規則
path('getpost/<int:id>/', views.getpost,name='home_getpost')

在需要使用 URL 的 html 頁面中可以使用 url 標籤進行動態的反向解析

<!-- URL反向解析.html -->
<!-- {% url '路由名' 路由捕獲引數 %} -->
<a href="{% url 'home_getpost' 8 %}">URL - 反向解析</a>

URL 反向解析的使用場景

  • html模板中:使用 url 標籤來反向解析
  • python程式碼中:使用 reverse() 進行反向解析,django.url.reverse