一、視圖
在mysite/misite(和__init__.py一個目錄)中,創建一個view.py文件:
from django.http import HttpResponse
def hello(request):
return HttpResponse("Hello,World!")
每個視圖函數至少要有一個參數,通常被叫作request。 這是一個觸發這個視圖、包含當前Web請求信息的對象,是類django.http.HttpRequest的一個實例。在這個示例中,雖然不用request做任何事情,然而它仍必須是這個視圖的第一個參數。一個視圖就是Python的一個函數。這個函數第一個參數的類型是HttpRequest;它返回一個HttpResponse實例。爲了使一個Python的函數成爲一個Django可識別的視圖,它必須滿足這兩個條件。
執行 django-admin.py startproject 時,該腳本會自動建立一份 URLconf(即 urls.py 文件):
如果想在URLconf中加入URL和view,只需增加映射URL模式和view功能的Python tuple即可. 這裏演示如何添加view中hello功能。
from django.conf.urls.defaults import *
from mysite.views import hello
urlpatterns = patterns('',
('^hello/$', hello),
)
對urls.py文件做了兩處修改:
- 從模塊 (在 Python 的 import 語法中, mysite/views.py 轉譯爲mysite.views ,mysite稱爲包) 中引入了hello 視圖。
- 爲urlpatterns加上一行:(‘^hello/$’, hello),這行被稱作URLpattern,它是一個Python的元組。元組中第一個元素是模式匹配字符串(正則表達式);第二個元素是那個模式將使用的視圖函數。
簡單來說,就是告訴 Django,所有指向 URL /hello/ 的請求都應由hello 這個視圖函數來處理。
Django在檢查URL模式前,移除每一個申請的URL開頭的斜槓(/)。 這意味着爲/hello/寫URL模式不用包含斜槓(/)。如果有人申請訪問/hello(尾部沒有斜槓/)會怎樣。 因爲URL模式要求尾部有一個斜槓(/),那個申請URL將不匹配。 然而,默認地,任何不匹配或尾部沒有斜槓(/)的申請URL,將被重定向至尾部包含斜槓的相同字眼的URL。 (這是受配置文件setting中APPEND_SLASH項控制的)。
另外需要注意的是,hello視圖函數是作爲一個對象傳遞,而不是在調用它。 這是 Python (及其它動態語言的) 的一個重要特性: 函數是一級對象(first-class objects), 也就是說可以像傳遞其它變量一樣傳遞它們。
一切都從settings.py開始。運行python manage.py runserver後,腳本將在於manage.py同一個目錄下查找名爲settings.py的文件。這個文件包含了所有有關這個Django項目的配置信息,均大寫: TEMPLATE_DIRS , DATABASE_NAME, 等. 最重要的設置是ROOT_URLCONF,它將作爲URLconf告訴Django在這個站點中那些Python的模塊將被用到。當運行python manage.py run server後,生成的settings.py文件中的ROOT_URLCONF指向自動生成的urls.py文件,settings.py文件中會有ROOT_URLCONF=’mysite.urls‘這樣一行語句。當訪問 URL /hello/ 時,Django 根據ROOT_URLCONF 的設置裝載 URLconf 。 然後按順序逐個匹配URLconf裏的URLpatterns,直到找到一個匹配的。 當找到這個匹配 的URLpatterns就調用相關聯的view函數,並把HttpRequest 對象作爲第一個參數。
總結如下:
- 轉入/hello/請求
- Django根據ROOT_CONF來決定根URLCONF
- Django根據在URLCONF中的所有URL模式中,查找第一個匹配/hello/的條目
- 如果找到匹配,將調用相應的視圖函數
- 視圖函數返回一個HttpResponse對象
- Django把HttpResponse轉換成合適的http response,在網頁中顯示出來。
三、動態視圖
構建一個顯示時間的/time/網頁,相應的view函數進行了修改:
在URL的匹配條目中添加('^time/$',current_time)後,顯示結果如下:
四、動態URL
在 大多數動態web應用程序,URL通常都包含有相關的參數。創建第三個視圖來顯示當前時間和加上時間偏差量的時間,設計是這樣的: /time/plus/1/ 顯示當前時間+1個小時的頁面 /time/plus/2/ 顯示當前時間+2個小時的頁面 /time/plus/3/ 顯示當前時間+3個小時的頁面,以此類推。
之前用PHP的時候可能會用到查詢字符串參數, 就像/time/plus?hours=3這樣,偏差小時在查詢字符串中被參數hours指定(問號後面的是參數)。但是Django的一個核心理念就是URL必須看起來漂亮。 URL/time/plus/3/ 更加清晰, 更簡單,也更有可讀性,可以很容易的大聲念出來,因爲它是純文本,沒有查詢字符串那麼 複雜。 漂亮的URL就像是高質量的Web應用的一個標誌。Django的URL配置系統可以使你很容易的設置漂亮的URL。
使用通配符來匹配任意數量的時差
urlpatterns = patterns('',
# ...
(r'^time/plus/(\d+)/$', hours_ahead),
# ...
)
這個URL模式將匹配類似 /time/plus/2/ ,/time/plus/25/ ,甚至 /time/plus/100000000000/ 的任何URL。
hous_ahead代碼:
from django.http import Http404, HttpResponse
import datetime
def hours_ahead(request, offset):
try:
offset = int(offset)
except ValueError:
raise Http404()
dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
return HttpResponse(html)
需要注意的有兩點:
- offset 是從匹配的URL裏提取出來的。 例如:如果請求URL是/time/plus/3/,那麼offset將會是3;如果請求URL是/time/plus/21/,那麼offset將會是21。請注意:捕獲值永遠都是字符串(string)類型,而不會是整數(integer)類型,即使這個字符串全由數字構成(如:“21”)。
結果示例圖:
P.S:
- 注意鬆耦合:模塊化後,模塊之間的修改儘量不相互影響,這樣比較好進行維護。
- 之前一直放置print語句來進行調試,其實可以用 Django 出錯頁來做這些,而不用 print 語句。 在視圖的任何位置,臨時插入一個assert False 來觸發出錯頁。 然後,你就可以看到局部變量和程序語句了。以hours_ahead爲例:
def hours_ahead(request, offset):
try:
offset = int(offset)
except ValueError:
raise Http404()
dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
assert False
html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
return HttpResponse(html)
結果如下: