一、簡單的小demo來描述django處理流程
1.建立視圖(view)
首先在當前目錄中新建一個views.py(視圖),然後編輯如下:(其實在後面教程中,這只是我們手動建立的,我們完全可以建立一個app,其中就包含它)(我們也可以先建立url映射,在建立對應的視圖函數)
1 #coding=utf-8 2 3 #從django.http模塊中導入HttpResponse類[1] 4 from django.http import HttpResponse 5 import datetime 6 7 def current_datetime(request): #[2] 8 now=datetime.datetime.now() 9 html="<html><body>現在時刻:%s.</body></html>" %now 10 return HttpResponse(html)
注意:這是一段很簡單、簡陋的例子,具體優化見後面介紹
分析:
[1].HttpResponse類位於django.http模塊中,是自己手動創建,與Django自動創建的HttpRequest對象不同,在每一個視圖(views)都需要實例化、處理、返回一個HttpResponse對象。
一般情況下,創建一個HttpResponse時,以字符串的形式傳遞頁面內容給HttpResponse構造函數:
1 >>>response=HttpResponse('I am BeginMan! ') 2 >>>response=HttpResponse('HelloWorld',mimetype='text/plain')
如果希望增加內容,則可以把response當做一個類文件對象來使用:
1 response=HttpResponse() 2 response.write("<p>i am beginman </p>") 3 response.write("<p>coding for fun! </p>")
其他具體信息見《Django Book》附錄內容
[2].在這個(views.py)視圖中每一個函數稱作視圖函數,視圖函數都以一個HttpRequest對象爲第一個參數,該參數通常命名爲request
2.URL映射視圖
url就像一座橋樑,通過這個橋樑我們才找到視圖中對應的代碼,渲染的模板(這一章暫時沒有將到模板),而這一切都通過一個叫URLConf(即urls.py)的東東,在我們django-admin.py startproject mysite後,該腳本會自動建立一份URLConf(即urls.py文件),我們可以在settings.py中找到它的真身,如下:
1 。。。。。。 2 ROOT_URLCONF = 'mysite.urls' 3 。。。。。。省略
urls.py打開如下:
1 from django.conf.urls.defaults import * #[1] 2 3 # Uncomment the next two lines to enable the admin: 4 # from django.contrib import admin 5 # admin.autodiscover() 6 7 urlpatterns = patterns('', #[2] 8 # Example: 9 # (r'^mysite/', include('mysite.foo.urls')), 10 11 # Uncomment the admin/doc line below to enable admin documentation: 12 # (r'^admin/doc/', include('django.contrib.admindocs.urls')), 13 14 # Uncomment the next line to enable the admin: 15 # (r'^admin/', include(admin.site.urls)), 16 )
分析:
[1].從django.conf.urls.defaults導入所有對象,其中包括了一個叫做patterns的函數
[2].patterns()函數將處理結果保存到urlpatterns變量中,注意patterns(' ',)有塊空白,它的存在就是之前的在瀏覽器顯示的it worked 的作用。
具體URL配置見另一篇博文:"URL常用配置"
我們編輯該文件以展示current_datetime視圖:
1 from django.conf.urls.defaults import * 2 from mysite.views import current_datetime 3 4 urlpatterns = patterns('', 5 (r'^time/$',current_datetime) 6 )
patterns函數中的參數其實就是一個元祖,前邊是一個正則表達式的,後邊是對應的視圖函數,(在本demo中)在瀏覽器中通過輸入http://127.0.0.1:8000/time ,Django在URLconf中的所有URL模式中,查找第一個匹配/time/的條目。如果匹配成功,則視圖函數返回一個HttpResponse,調用current_datetime這個視圖函數,Django轉換HttpResponse爲一個適合的HTTP response, 以Web page顯示出來,(在沒有模板定義的情況下)顯示輸出結果。
至此這一系列Django簡單的處理流程就完成了。
二、Django處理請求的工作機制
記住:
1.用manage.py runserver 啓動Django服務器時就載入了在同一目錄下的settings.py。該文件包含了項目中的配置信息,如前面將的URLConf等,其中最重要的配置就是ROOT_URLCONF,它告訴Django哪個Python模塊應該用作本站的URLConf,默認的是urls.py
2.當訪問url的時候,Django會根據ROOT_URLCONF的設置來裝載URLConf。
3.然後按順序逐個匹配URLConf裏的URLpatterns。如果找到則會調用相關聯的視圖函數,並把HttpRequest對象作爲第一個參數(通常是request)
4.最後該view函數負責返回一個HttpResponse對象,
四、深入一步:動態URL
上面一個簡單的例子介紹了動態的內容,接下來深入一下url的映射,實現動態的url。
我們要做到就是在url後輸入一些參數,從而實現不同的調用內容(如在url後輸入數字(小時)來顯示當前時間累加後的時間,如當前時間是6:20,在瀏覽器中輸入....time/plus/3,則顯示9:20)的小實例(可參見《Django Book》)
我們可以有三種不同的方法來實現:
第一種:全部寫入到url中
1 urlpatterns = patterns('', 2 (r'^time/$',current_datetime), 3 (r'^time/plus/1/$',one_hour_ahead), 4 (r'^time/plus/2/$',two_hour_ahead), 5 (r'^time/plus/3/$',three_hour_ahead), 6 ............................... 7 .................. 8 )
這種不解釋,累死寫不完。pass
第二種:URL查詢字符串的形式,以?來實現,如/time/plus?hours=3。這一種在asp.net中常見的一種方式,但是在django中,它會顯得臃腫、低效。pass
第三種:帶通配符的URL匹配模式
因爲URL模式是一個正則表達式,因此,可以使用正則表達式的技巧和URL配置技巧來實現。具體見另兩篇博文:Python零碎知識(5):有關正則表達式和Django總結(1):URL常用配置方法
對於本實例,可以使用 \d+ 來匹配一個或多個數字:
1 urlpatterns = patterns('', 2 (r'^time/$',current_datetime), 3 (r'^time/plus/\d+/$',hours_ahead), 4 (r'^time/plus/(\d{1,2})/$',hours_ahead),#或者限制最大允許99 5 )
然後我們在編寫hours_ahead視圖函數,整理如下:
1 #coding=utf-8 2 3 #從django.http模塊中導入HttpResponse類[1] 4 from django.http import HttpResponse 5 import datetime 6 7 def current_datetime(request): #[2] 8 now=datetime.datetime.now() 9 html="<html><body>現在時刻:%s.</body></html>" %now 10 return HttpResponse(html) 11 12 def hours_ahead(request,offset): 13 offset=int(offset) 14 dt=datetime.datetime.now()+datetime.timedelta(hours=offset) 15 html="<html><body>In %s hours it will be %s.</body></html>" %(offset,dt) 16 return HttpResponse(html)
注意:hours_ahead有兩個參數,第一個request,之前已經討論過;第二個參數offset是從匹配的URL裏提取出來的,如/time/plus/10,則提取offset是10(注意字符串要int成整數才能相加)
五、小結
主要掌握了:1.url映射基礎、2.視圖函數、3.Django處理請求的工作機制、4.動態URL思想