Django - URL 路由



現在我們已經有了一個像前面章節解釋的那樣工作的檢視。我們想透過一個 URL 訪問該檢視。Django 有自己獨特的 URL 路由方式,可以透過編輯你的專案 url.py 檔案 **(myproject/url.py)** 來完成。url.py 檔案看起來像這樣:

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
   #Examples
   #url(r'^$', 'myproject.view.home', name = 'home'),
   #url(r'^blog/', include('blog.urls')),

   url(r'^admin', include(admin.site.urls)),
)

當用戶請求你的 web 應用上的一個頁面時,Django 控制器接管,透過 url.py 檔案查詢對應的檢視,然後返回 HTML 響應或 404 未找到錯誤(如果未找到)。在 url.py 中,最重要的事情是 **"urlpatterns"** 元組。你在這裡定義 URL 和檢視之間的對映。URL 模式中的對映是一個元組,例如:

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
   #Examples
   #url(r'^$', 'myproject.view.home', name = 'home'),
   #url(r'^blog/', include('blog.urls')),

   url(r'^admin', include(admin.site.urls)),
   url(r'^hello/', 'myapp.views.hello', name = 'hello'),
)

標記行將 URL "/home" 對映到在 myapp/view.py 檔案中建立的 hello 檢視。如你所見,對映由三個元素組成:

  • **模式** - 一個匹配你想要解析和對映的 URL 的正則表示式。任何可以與 python 的 're' 模組一起工作的正則表示式都適用於模式(當你想要透過 url 傳遞引數時很有用)。

  • **檢視的 python 路徑** - 與匯入模組時相同。

  • **名稱** - 為了執行 URL 反向解析,你需要使用上面示例中所做的命名 URL 模式。完成後,只需啟動伺服器即可透過 :http://127.0.0.1/hello 訪問你的檢視。

組織你的 URLs

到目前為止,我們已經在 “myprojects/url.py” 檔案中建立了 URLs,但是正如前面關於 Django 和建立應用程式所述,最佳方案是能夠在不同的專案中重用應用程式。如果你將所有 URLs 儲存在 “projecturl.py” 檔案中,你很容易就能看出問題所在。因此,最佳實踐是為每個應用程式建立一個 “url.py” 檔案,並將其包含在我們的主專案 url.py 檔案中(我們之前包含了 admin 介面的 admin URLs)。

Organize URLs

怎麼做?

我們需要使用以下程式碼在 myapp 中建立一個 url.py 檔案:

from django.conf.urls import patterns, include, url

urlpatterns = patterns('', url(r'^hello/', 'myapp.views.hello', name = 'hello'),)

然後 myproject/url.py 將更改為以下內容:

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
   #Examples
   #url(r'^$', 'myproject.view.home', name = 'home'),
   #url(r'^blog/', include('blog.urls')),

   url(r'^admin', include(admin.site.urls)),
   url(r'^myapp/', include('myapp.urls')),
)

我們已經包含了來自 myapp 應用程式的所有 URLs。以前透過 “/hello” 訪問的 home.html 現在是 “/myapp/hello”,這對於 web 應用來說是一個更好、更容易理解的結構。

Myproject

現在讓我們假設我們在 myapp 中有另一個檢視 “morning”,並且我們想在 myapp/url.py 中對映它,那麼我們將更改我們的 myapp/url.py 為:

from django.conf.urls import patterns, include, url

urlpatterns = patterns('',
   url(r'^hello/', 'myapp.views.hello', name = 'hello'),
   url(r'^morning/', 'myapp.views.morning', name = 'morning'),
)

這可以重構為:

from django.conf.urls import patterns, include, url

urlpatterns = patterns('myapp.views',
   url(r'^hello/', 'hello', name = 'hello'),
   url(r'^morning/', 'morning', name = 'morning'),)

如你所見,我們現在使用 **urlpatterns** 元組的第一個元素。當你想要更改你的應用名稱時,這很有用。

URL Patterns

向檢視傳送引數

我們現在知道如何對映 URL,如何組織它們,現在讓我們看看如何向檢視傳送引數。一個經典的例子是文章示例(你想要透過 “/articles/article_id” 訪問一篇文章)。

傳遞引數是透過在 URL 模式中使用 **正則表示式** 來捕獲它們來完成的。如果我們在 “myapp/view.py” 中有一個像下面的檢視

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

def hello(request):
   return render(request, "hello.html", {})

def viewArticle(request, articleId):
   text = "Displaying article Number : %s"%articleId
   return HttpResponse(text)

我們想在 myapp/url.py 中對映它,以便我們可以透過 “/myapp/article/articleId” 訪問它,我們需要在 “myapp/url.py” 中新增以下內容:

from django.conf.urls import patterns, include, url

urlpatterns = patterns('myapp.views',
   url(r'^hello/', 'hello', name = 'hello'),
   url(r'^morning/', 'morning', name = 'morning'),
   url(r'^article/(\d+)/', 'viewArticle', name = 'article'),)

當 Django 看到 url:“/myapp/article/42” 時,它會將引數 '42' 傳遞給 viewArticle 檢視,在你的瀏覽器中,你應該得到以下結果:

Passing parameters to viewArticle

請注意,這裡的引數順序很重要。假設我們想要某個年份某個月份的文章列表,讓我們新增一個 viewArticles 檢視。我們的 view.py 變成:

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

def hello(request):
   return render(request, "hello.html", {})

def viewArticle(request, articleId):
   text = "Displaying article Number : %s"%articleId
   return HttpResponse(text)

def viewArticle(request, month, year):
   text = "Displaying articles of : %s/%s"%(year, month)
   return HttpResponse(text)

相應的 **url.py** 檔案將如下所示:

from django.conf.urls import patterns, include, url

urlpatterns = patterns('myapp.views',
   url(r'^hello/', 'hello', name = 'hello'),
   url(r'^morning/', 'morning', name = 'morning'),
   url(r'^article/(\d+)/', 'viewArticle', name = 'article'),
   url(r'^articles/(\d{2})/(\d{4})', 'viewArticles', name = 'articles'),)

現在當你訪問 “/myapp/articles/12/2006/” 時,你將得到 'Displaying articles of: 2006/12',但是如果你反轉引數,你將不會得到相同的結果。

Displaying Articles

為了避免這種情況,可以將 URL 引數連結到檢視引數。為此,我們的 **url.py** 將變為:

from django.conf.urls import patterns, include, url

urlpatterns = patterns('myapp.views',
   url(r'^hello/', 'hello', name = 'hello'),
   url(r'^morning/', 'morning', name = 'morning'),
   url(r'^article/(\d+)/', 'viewArticle', name = 'article'),
   url(r'^articles/(?P\d{2})/(?P\d{4})', 'viewArticles', name = 'articles'),)
廣告