django:理解urls路由


最近在看django的官方文檔,跟着文檔敲第一個django應用,剛開始看到第一部分關於urls路由的設置時,腦子里冒出來許多問號

一時沒轉過彎來,它到底是咋轉發路由的??如何通過我配置的路徑來定位到指定視圖的?

然后自己就反復試驗了幾次,又仔細看了文檔中的描述(我的蹩腳英語不足以支撐看原版英文文檔,看的英譯漢,所以翻譯后有些字眼確實不好理解,沒內個味道了...)

OK,閑話到此為止,繼續往下看

首先,我的django項目層級如下

mysite/urls.py 是根 URLconf 文件

polls/urls.py 是一個應用下的 URLconf 文件

 polls/urls.py 中添加了路由

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

然后在 mysite/urls.py 文件的 urlpatterns 列表里插入一個 include()

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

urlpatterns = [
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]

第一種情況

 官方文檔有這樣一句話:

每當Django遇到include(),它都會截斷直到該時間點匹配的URL的任何部分,並將剩余的字符串發送到包含的URLconf中以進行進一步處理。

上面的這段話有2個關鍵點:截斷已經匹配到的部分將剩下的部分繼續送給include()指定的URLconf文件

然后按照如下步驟進行分析:

  1. 當在瀏覽器輸入一段url,它會首先根據 mysite/urls.py  文件中 urlpatterns 包含的 path 匹配
  2. 例如輸入url為:http://127.0.0.1:8000/polls/,那么它會以這串url中的 polls/ 進行匹配 
  3. mysite/urls.py 文件中,發現 urlpatterns 內的第一個 path 就是polls/ ,匹配成功
  4. 截斷這個url已經匹配的部分,所以 http://127.0.0.1:8000/polls/ 截斷后只剩下空字符串 ''
  5. 接下來就把空字符串 '' 繼續送給 include('polls.urls') 包含的 URLconf 文件進行處理,這里的話,就是送給投票應用 polls 自己的 URLconf 文件來繼續匹配這個剩下的空字符串 ''
  6. 觀察 polls/urls.py 中urlpatterns包含的 path,第一個 path 就是空字符串 '',匹配成功,所以最終這個url就映射到了這個空字符串對應的視圖 index

所以如果訪問 http://127.0.0.1:8000/polls/ 等價於訪問 http://127.0.0.1:8000/polls/ + 空字符串

第二種情況

如果上面的空字符串不好理解,可以再換個url,例如url為 http://127.0.0.1:8000/polls/test/

 mysite/urls.py 內容如下

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

urlpatterns = [
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]

polls/urls.py 中內容如下

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('test/', views.index2, name='index2'), # 添加了一個新路由,映射到index2視圖
]

視圖文件 polls/views.py 添加了一個index2()函數

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.

def index(request):
    return HttpResponse("hello, world")

def index2(request):
    return HttpResponse("測試匹配路由test")

按照如下思路進行分析:

  1. 在瀏覽器輸入url:  http://127.0.0.1:8000/polls/test/,它還是先在 mysite/urls.py 文件中以后綴polls/test/” 匹配路由,可以發現 polls/ 匹配成功
  2. 截斷url后,剩下 test/ ,將其發送給投票應用 polls 的URLconf文件繼續處理,也就是 polls/urls.py
  3. 觀察 polls/urls.py 中 urlpatterns 包含的path,第一個path是 '',匹配失敗;第二個path是 test/,匹配成功,所以這個url就映射到了其對應的視圖,也就是 views.index2

訪問url,結果如下,確實映射到了視圖函數index2()對應的內容

第三種情況

一個django項目下可以有多個應用(app),上面的示例中只有一個應用polls

接下來再在這個項目新建一個應用,名稱為blog

然后在blog下新建一個urls.py文件

 在 blog/views.py 文件中添加一個視圖

from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.


def index(request):
    return HttpResponse("hello, welcome to blog")

blog/urls.py 文件中添加path

from django.urls import path
from blog import views

urlpatterns = [
    path('index/', views.index, name='index'),
]

然后在根urlconf文件,也就是mysite/urls.py 文件中指定blog.urls模塊

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

urlpatterns = [
    path('polls-admin/', admin.site.urls),
    path('polls/', include('polls.urls')),
    path('blog/', include('blog.urls')),  # 指定blog.urls模塊
]

這個時候如果在瀏覽器輸入 http://127.0.0.1:8000/blog/index/

根據上面的經驗,它會先定位到 blog/ ,然后到blog下的urls文件中繼續匹配  index/ ,如果匹配成功,則映射到 blog/views.py 下定義的index視圖

訪問結果如下

 如果修改 blog/urls.py 文件,把path中的 index/ 改為 index2/

from django.urls import path
from blog import views

urlpatterns = [
    path('index2/', views.index, name='index'),
]

這個時候再訪問 http://127.0.0.1:8000/blog/index/,就會報錯了,因為這個時候是 index2/ 關聯 index 視圖,而 index/ 這個路徑沒有映射(關聯)任何視圖了,此時會報404

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM