我的筆記是學習http://djangobook.py3k.cn/ 課程時做的,這個上邊的文章講的確實是非常的詳細,非常感謝你們提供的知識。
上一篇隨筆中已經配置好了Django環境,現在繼續跟隨http://djangobook.py3k.cn/chapter03/ 來學習網頁顯示時間這個小功能:
這個簡單的范例僅輸出服務器的內部時鍾,如圖
開發的環境是CentOS6.7
首先,創建一個網頁:views.py
from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
簡單分析一下該代碼:
函數current_datetime的第一段代碼用來獲取當前的時間並賦值給變量now;
第二段代碼使用 Python 的格式化字符串(format-string)功能構造了一段 HTML 響應。字符串里面的 %s 是占位符,字符串之后的百分號表示使用變量 now 的值替換 %s;
最后,該視圖返回一個包含所生成響應的 HttpResponse 對象.
然后修改URL映射:
views.py中的視圖函數返回了包含當前日期和時間的一段 HTML 頁面。但是如何告訴 Django 使用這段代碼呢?這就時候就需要 URLconfs 了。
URLconf就是一個映射表,用來調用函數視圖。用它來告訴 Django,對於這個 URL 調用這段代碼,對於那個 URL 調用那段代碼。
上一節中執行 django-admin.py startproject 時,該腳本會自動為你建了一份 URLconf(即 urls.py 文件)。
from django.conf.urls.defaults import * urlpatterns = patterns('', # Example: # (r'^mysite/', include('mysite.apps.foo.urls.foo')), # Uncomment this for admin: # (r'^admin/', include('django.contrib.admin.urls')), )
分析:
urlpatterns 變量定義了 URL 以及用於處理這些 URL 的代碼之間的映射關系, Django 期望能從 ROOT_URLCONF 模塊中找到它。
現在修改該文件:
from django.conf.urls.defaults import * from mysite.views import current_datetime urlpatterns = patterns('', (r'^time/$', current_datetime), )
分析:
首先,模塊中引入了 current_datetime 視圖。接着,我們加入了 (r'^time/$', current_datetime)這就是 URLpattern ,它是一個 Python 元組,其第一個元素是簡單的正則表達式,第二個元素是為該模式應用的視圖函數。
注意:
我們將 current_datetime 視圖函數作為對象傳遞,而不是調用它。這是 Python (及其它動態語言的) 的一個重要特性:函數是一級對象(first-class objects), 也就是說你可以像傳遞其它變量一樣傳遞它們。
r'^time/$' 中的 r 表示 '^time/$' 是一個原始字符串。這樣一來就可以避免正則表達式有過多的轉義字符。
不必在 '^time/$' 前加斜杠(/)來匹配 /time/ , 因為 Django 會自動在每個表 達式前添加一個斜杠。乍看起來,這好像有點奇怪,但是 URLconfs 可能由其它的 URLconfs 所引用, 所以不加前面的斜杠可讓事情簡單一些。
上箭頭 ^ 要求表達式對字符串的頭部進行匹配,美元符號 $ 則要求表達式對字符串的尾部進行匹配。
最好還是用范例來說明一下這個概念。如果我們用 '^time/' (結尾沒有$), 那么以 time/ 開始的 任意 URL 都會匹配,比如 /time/foo 和 /time/bar , 不僅僅是 /time/ 。同樣的,如果我們去掉最前面的 ^ ( 'time/$' ), Django 一樣會匹配由 time/ 結束的 任意 URL /time/ ,比如/foo/bar/time/ 。 因此,我們必須同時用上 ^ 和 $ 來精確匹配 URL /time/ 。不能多也不能少。
瀏覽器訪問 http://127.0.0.1:8000/time/ 應該就可以看到開頭的網頁顯示時間的效果了。
Django處理請求的過程
python manage.py runserver
執行上面的命令,從同一目錄載入文件 settings.py 。 該文件包含了這個特定的Django實例所有的各種可選配置,其中一個最重要的配置就是 ROOT_URLCONF 。
ROOT_URLCONF
告訴Django哪個Python模塊應該用作本網站的 URLconf。
通過命令
django-admin.py startproject
會創建文件 settings.py 和 urls.py , 這是系統自動生成的 settings.py 里 ROOT_URLCONF 默認設置是 urls.py 。
當訪問 URL /time/ 時,Django 根據 ROOT_URLCONF 的設置裝載 URLconf 。 然后按順序逐個匹配URLconf里的URLpatterns,直到找到一個匹配的。當找到這個匹配 的URLpatterns就調用相關聯的view函數,並把 HttpRequest 對象作為第一個參數。
該 view 函數負責返回一個 HttpResponse 對象。
你現在知道了怎么做一個 Django-powered 頁面了,真的很簡單,只需要寫視圖函數並用 URLconfs把它們和URLs對應起來。你可能會認為用一系列正則表達式將URLs映射到函數也許會比較慢,但事實卻會讓你驚訝。
動態URL事例:
目標: /time/plus/1/ 顯示當前時間+1個小時的頁面
/time/plus/2/ 顯示當前時間+2個小時的頁面,以此類推。
不建議的寫法:
urlpatterns = patterns('', (r'^time/$', current_datetime), (r'^time/plus/1/$', one_hour_ahead), (r'^time/plus/2/$', two_hours_ahead), (r'^time/plus/3/$', three_hours_ahead), (r'^time/plus/4//$', four_hours_ahead), )
采用漂亮URL的方式
可以使用正則表達式模式 \d+ 來匹配一個或多個數字:
from django.conf.urls.defaults import * from mysite.views import current_datetime, hours_ahead urlpatterns = patterns('', (r'^time/$', current_datetime), (r'^time/plus/\d+/$', hours_ahead), )
這個URL模式將匹配類似 /time/plus/2/ , /time/plus/25/ ,甚至 /time/plus/100000000000/ 的任何URL。更進一步,讓我們把它限制在最大允許99個小時, 這樣我們就只允許一個或兩個數字,正則表達式的語法就是 \d{1,2} :
(r'^time/plus/\d{1,2}/$', hours_ahead),
現在我們已經設計了一個帶通配符的URL,我們需要一個方法把它傳遞到視圖函數里去,這樣 我們只用一個視圖函數就可以處理所有的時間段了。我們使用圓括號把參數在URL模式里標識 出來。在這個例子中,我們想要把這些數字作為參數,用圓括號把 \d{1,2} 包圍起來:
(r'^time/plus/(\d{1,2})/$', hours_ahead),
正則表達式也是用圓括號來從文本里 提取 數據的
最終的結果
from django.conf.urls.defaults import * from mysite.views import current_datetime, hours_ahead urlpatterns = patterns('', (r'^time/$', current_datetime), (r'^time/plus/(\d{1,2})/$', hours_ahead), )
views文件中包含了兩個視圖
from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html) def hours_ahead(request, offset): offset = int(offset) 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里提取出來的參數
注意:在 offset 上調用 int() . 這會把這個字符串值轉換為整數。
http://djangobook.py3k.cn/chapter03/ 書中的講解十分精彩,實在無法模仿,只拿出一些片段作為筆記,要想體會其中精華,必須查看原書。