over 3 years ago

  • 第一個視圖:媽,我在這裡
    • 設定urls.py
    • 撰寫視圖函式
    • 我想用中文
  • 第二個視圖:網址計算機

第一個視圖:媽,我在這裡

要完成一個可以回應給使用者的頁面,相當相當容易,主要有兩個步驟

1. 設定urls.py
2. 撰寫視圖函式

設定urls.py

打開我們的urls.py,你會看到在裡面有一些基本的設定了

mysite/mysite/urls.py
from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Examples:

    # url(r'^$', 'myweb.views.home', name='home'),

    # url(r'^blog/', include('blog.urls')),

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

這個設定檔主要的精神就在於他利用urlpatterns這個變數來進行pattern與action的對應,這是什麼意思咧?這裡所謂的pattern指的是在URL中出現在網域後面的東東,舉例來說

127.0.0.1:8000/here/

該URL中的/here/就是我們所說的pattern,當使用者輸入這個pattern的時候,我們應該採取的動作(從準備資料到回應瀏覽器),就是action,而action會是一個function,通常會放置在views.py這個檔案裡面,對於這種對應,我們需要一個對應表,那就是urlpatterns的功用了!

首先注意到,urlpatterns這個元組的首個元素是個空字串,這個目前我們先不動他,再來的每一個元素都會是一個url/action對應,那我們試著為/here/這個pattern加入他相應的動作吧(一些code在這邊進行省略):

from views import here                            # 從views.py中匯入here這個function

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    url(r'^here/$', here),                        # 加入此行

)

這邊停下來對r'^here/$'做個解說,這是Python中正規表達式的寫法,^號代表配對開始,$號代表配對結束,所以該表達式代表的是網域後的字串要"完全"等於/here/才算配對成功,值得注意的是,here前面並沒有寫出/,這是因為Django預設會幫你加上這個slash。另外,$號但表了配對結束,所以任何

在匯入的部份做個說明,因為等等我們要撰寫的views.py會放置在與urls.py同一個資料夾中,所以使用from views import here是沒問題的,但為求嚴謹,我們可以使用標準路徑(還記得我們的BASE_DIR設的是上層mysite嗎?)來匯入,改為from mysite.views import here,這裡的mysite則指的是下層mysite。別被搞混啦!

其實講簡單一點,url(r'^here/$', here)就是告訴Django,看到網域後面出現/here/就去callviews.py裡面的functionhere來動作,如此而已。

撰寫視圖函式

我們可不能唬爛Django,光有對應表但是卻沒有實際的動作存在,那會是有問題的!,馬上在子目錄mysite下面產生一個views.py並完成here這個function吧:

mysite/mysite/views.py
from django.http import HttpResponse

def here(request):
    return HttpResponse('Mom, I am here!')

我們來詳細了解一下here這個function,首先,這類回應pattern的action function都要以request為第一個變數,request是一個有關使用者請求的物件HttpRequest,要這樣想,有求才有應,有問才有答,你的回應一定伴隨著一個要求,所以任何action都把request設為第一個參數吧。

再來,我們簡單的回傳了一個HttpResponse物件,你必須記得從django.http中匯入,這是一個很基礎的回應物件,參數可以是一個字串或一個完整的html,目前我們回傳一個字串就好。here這個function將會在使用者發出/here/pattern來求取頁面時,show出一個只包含'Mom, Iam here!'字串的回應。

以上都設置完成後,讓我們啟動server(如果你從頭到尾都沒關閉的話,不用重啟,django會在你每一次更動專案中檔案時,自動重啟),啟動server你忘記了嗎?這裡幫大家複習:

$ python manage.py runserver

太棒了!很簡單地(還是你覺得很複雜xd),第一個自己撰寫的頁面就完成囉。

我想用中文

好了,我們不能老是用英文,畢竟寫在地的應用服務時,很多資料都會是中文的吧,那我們就來試試看把'Mom, I am here!'改成中文'媽,我在這裡!'。你可能覺得我在說廢話,在settings.py中語言都設置為'zh-TW'了,應該只要簡單的修改views.py就可以了吧,於是:

mysite/mysite/views.py
from django.http import HttpResponse

def here(request):
    return HttpResponse('媽,我在這!')

然後就悲劇了,你將會在browser上面看到SyntaxError at /here/,然後又臭又長的錯誤訊息,到底怎麼辦呢?難道不給說中文嗎!喔,別擔心,簡單的在views.py中加入我們親切的utf-8編碼說明就ok囉:

mysite/mysite/views.py
# -*- coding: utf-8 -*-

from django.http import HttpResponse

def here(request):
    return HttpResponse('媽,我在這!')

果然不再有錯了,顯示中文,我們可以!

但在接下去之前,我希望大家能夠去回味一下剛剛的錯誤訊息頁面,裡面提供了相當大量的資訊與狀態值,這對於除錯來說,比起原本的python直譯器是強了不少,尤其是很會鬼打牆的web design,好好看看他給了哪些訊息,有哪些功能,在往後開發的道路上,才能輕鬆除蟲,走地順暢!

在接下去之前,大家可能有個問題想問,究竟是先撰寫視圖函數呢?還是應該先做URL的配置?這取決於個人狀況,不過有一點相當重要,我們應當保持各元件的之間的低依賴性,這點Django原先的設計就做的很好了,想一想,今天如果我想要把進行'媽,我在這!'的URL改變,我只需要動到urls.py這個檔案,反過來,我想要對here這個view function進行修改,也不會影響到這個對應,互不影響!

在Django的應用程序中,URL的定義和視圖函數之間是鬆耦合的,換句話說,決定URL返回哪個視圖函數和實現這個視圖函數是在兩個不同的地方。這使得開發人員可以修改一塊而不會影響另一塊。

Django Book

第二個視圖:網址計算機

第一個例子,讓大家初步了解了,視圖函數和URL是怎麼搭配的,並且可以根據request做出response,但不管刷新幾次頁面,總是那一句:媽,我在這。實在是太無聊了,我們想來點刺激的,不如利用網址來做點加、減、乘、除吧。

我們就採行跟第一個例子一樣的步驟:

1. 設定urls.py
2. 撰寫視圖函數

比如說今天我想要利用URL來做加法(世界上會這樣做的只有我跟現在願意操作的你吧~)

打開urls.py加入pattern/action的對應

mysite/mysite/urls.py
from views import here, add

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    url(r'^here/$', here),
    url(r'^(\d{1,2})/plus/(\d{1,2})/$', add),
)

正規表達式中,\d{1,2}代表匹配一或兩個數字,簡單來說就是我們希望他是個一位數整數或二位數整數,0~99。比如說URL長這樣:127.0.0.1/23/plus/2將會匹配成功並且呼叫action:add

此處有個重點(本例的重點!),url(或者說pattern)中的某部分可以作為視圖函數的參數!怎麼做呢,使用兩個小括號將要作為參數的部分包起來就好,在這裡就是(\d{1,2}),第一個和第二個(\d{1,2})依序會成為add的第二個和第三個參數,什麼?第一個參數?難道你忘了所有的action都要以HttpRequest物件當做第一個參數嗎!好了,當我們了解這些之後,便可以著手撰寫add這個視圖函數。

mysite/mysite/views.py
# -*- coding: utf-8 -*-

from django.http import HttpResponse

def here(request):
    return HttpResponse('媽,我在這!')

def add(request, a, b):
    s = int(a)+int(b)
    return HttpResponse(str(s))
)

要注意的是,從URL傳入的參數一律是字串,所以該注意的型別轉換是需要的。好的,你現在已經可以陸續開發減法、乘法和除法了,很簡單吧。現在我們試著將四則運算的所有結果同時show在page上。

首先,我們對function的名字改做math(不單做加法了!),這將會動到兩個檔案,在urls.py中只需要將add改為math就好,在views.py中除了更換function name,我們還要增加若干個運算並且我們打算使用html來作為回應。(以後為了節省空間我們將只列出重點部分的code)

mysite/mysite/views.py
# -*- coding: utf-8 -*-

from django.http import HttpResponse

def math(request, a, b):
    a = int(a)
    b = int(b)
    s = a + b
    d = a - b
    p = a * b
    q = a / b
    html = '<html>sum={s}<br>dif={d}<br>pro={p}<br>quo={q}</html>'.format(s=s,d=d,p=p,q=q)
    return HttpResponse(html)
)

現在我們利用url,如:127.0.0.1/23/math/7就可以看到show出的頁面了,有和、差、積與商。但是大家有沒有覺得這樣寫出來的html非常難看呢(我承認我偷懶了,這個html根本不完整),當我們日後要加入css樣式或是javascript的時候想必會更醜。而且將view logic混到business logic來絕對是個壞主意,身為一個強大的MTV架構,Django的能耐不該只有如此,究竟少了什麼呢?你猜對了,就是MTV的T,模版(template)。

← Django筆記(1) - 建置與環境設定 Django筆記(3) - 模版初探 →
 
comments powered by Disqus