Model我們會建了,資料也可以從後台或Shell來做新增/修改/刪除/更新,網址會設定了,Template也大概知道怎麼回事了,其實整個Django的MTV(Model-Template-View)架構到這裡已經介紹得差不多了,接下來我們就是要把資料給串起來。
回來看一下先來看一下我們的book/views.py:
1 2 3 4 5 6 7 8 | |
接著,我們要來把資料給撈出來,並且把它餵給Template(我知道「撈」、「餵」這些詞有點台,不過我想大家比較聽得懂):
1 2 3 4 5 6 7 8 9 10 | |
我們在第6行把資料庫透過Book類別給取出來,然後在第7行再以dictionary型式傳給render_to_response,這樣待會我們在Template裡就可以取用得到books這個變數。
切換到Template templates/book/index.html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
打開瀏覽器,網址輸入:http://127.0.0.1:8000/,應該可以看到類似的畫面:

如果沒有看到列表的話,就先到佛心的Admin模組去新增個兩本書,再回來看一下結果。
那書的內容呢?
剛剛只有列表,接下來要把連結跟內容頁給做起來:
templates/book/index.html,在書名上加上連結:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
再來做一下內容templates/book/detail.html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
同時,book/views.py也要做些調整:
1 2 3 4 5 6 7 8 9 10 11 | |
這邊我又偷懶的用到了short_cuts模組的get_object_or_404,意思就是說如果資料庫裡面找不到這筆資料的話,就會直接丟出HTTP 404的畫面。
如果程式運作正常,你應該可以看到像這樣的畫面:

僅為展示效果,所以頁面很陽春,我相信你拿到設計師的HTML頁面應該都比這個漂亮許多倍。
Filters
到目前為止,程式看起來已經會動了!! 但長官可能看到畫面後,可能會神來一筆的說:「那個錢的單位,可以加上千位的逗點符號嗎?」,或是「那個出版日期..可以把年份放最前面,而且用斜線分開嗎?」。
你的第一個想法,可能會是資料撈出來之後,先每一筆都處理過之後再丟給Template。但事實上這種"資料呈現"的工作,應該只要交給Template的Filter來做就好。Template的Filter有點像在Linux系統上的pipe,就是可以透過|符號,把前面的資料丟給下一個執行,直到最後結束為止,來看一些範例:
1 2 3 4 5 6 7 8 9 10 | |
要注意的是,filter在用的時候,|的左右不可以有空白,不然會直接出現TemplateSyntaxError。其它更多的Filter,請參考:https://docs.djangoproject.com/en/1.3/ref/templates/builtins/
看完之後,認份的來完成剛剛老闆交待的修改吧!
出版日期的年份放前面,年、月、日各別用斜線分開
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
只改了一行就搞定了!
數字加上千位逗點符號
Django也有幫我們寫好這個filter,但因為這個模組預設並沒有安裝/載入,所以在使用上會稍微麻煩一些:
settings.py的INSTALLED_APPS要加上django.contrib.humanize模組:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
在使用之前需要用{% load humanize %}載入,然後就可以用了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
沒問題的話,應該是這個樣子:

打完收工,下班去了!
寫自己的Filter
有時候就是沒有現成的filter可以用(其實是不常發生..),例如老闆又說「那個日期的年份,可以改成民國年份表示嗎?」。大概猜也知道老外不太可能會幫我們寫這種filter,當然要硬改也不是不行,但就失去了我們用這個framework的原意了。我們就來寫個可以產生民國年份的filter吧(其實不過就是把年份減掉1911而已..)
filter本身其實也就是Python的程式碼而已,所以第一個問題應該會是:「filter要寫在哪裡?」
filter有固定的寫法跟位置,你可以把它寫在適合的App底下,它必須放在某個App的templatetags資料夾裡,而且因為它是一個標準的Python模組,所以在templatetags資料夾裡,它必須也要放一個__init__.py。在我們目前這個範例,我把它放在book這個App裡,模組的檔名我給它取做chinese_date.py,整個看起來的資料夾結構大概會長得像這樣:

再來,為了讓Django認得你寫的filter,你會需要有一個叫做register的template.Library實體變數,所以它的固定寫法會是長得像這樣:
1 2 3 4 5 6 7 8 | |
第1行加上encoding: utf-8是因為我們在程式裡面有用到中文字元,如果沒加這行的話會出現SyntaxError。第2、3行就是Django規定filter的固定寫的filter method,最後第8行再把它註冊起來,讓Django看得到它。第8行的註冊方式,也可以用method decorator的寫法:
1 2 3 4 5 6 7 | |
效果一樣,不過我個人比較偏好這種寫法。filter寫好了,最後回來原來的Template:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
{% load chinese_date %}載入剛剛寫好的模組,修改一下filter,最後得樣子應該會長這樣:

搞定,下班啦!
更多相關細節,請參考 https://docs.djangoproject.com/en/1.3/howto/custom-template-tags/
還有嗎?
到這裡,其實我們已經將Django的MTV架構跟流程介紹的差不多了,接下來請趁你還有記憶的時候,把官網的文件全部讀一遍吧!



