在上一個章節的Shell操作過程中,如果你有注意到的話,你會發現一段長得像這樣的東西:
>>> Profile.objects.all()
[<Profile: Profile object>]
但如果你想讓這個object能夠一眼就看得出來它是什麼內容的話,只要在Model的Profile類別裡覆寫一些method,我們再次打開author/models.py,原來的程式碼長這樣:
1 2 3 4 5 6 7 8 9 10 11 12 | |
我們來幫它加一個__unicode__的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
然後我們再到shell裡操作的時候,就會發現秀出來的資料變得不一樣了:
>>> from author.models import Profile
>>> eddie = Profile(name = "eddie kao", age = 30, tel = "0928123123", address = "Taipei, Taiwan", email = "eddie@digik.com.tw")
>>> eddie
<Profile: eddie kao>
看到了嗎? 它由原本的object變成會秀出名字了。其實原理就是當你在Python用print方法把物件給印出來的時候,它會呼叫這個類別裡實作的__str__、__repr__以及__unicode__,其實這三個有一些些微的差異,細節可參考Python的文件說明,這裡我們直接覆寫Profile類別的__unicode__方法,讓它回傳name欄位的值。這樣的修改,稍候你在後台看資料的時候,也會發現它會由原本的object,變成秀出你設定的name欄位。
事實上,你還可以定義更多的方法,把一些程式邏輯給包在Model裡,這樣一來,你在View(Controller)的地方就可以讓程式碼變得更簡潔,也更容易維護。例如我們來簡單寫個檢查該名作者是否已經成年(年齡 > 18):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
再來進到shell裡看看:
> bookstore python manage.py shell
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from author.models import Profile
>>> author = Profile.objects.get(id = 1)
>>> author
<Profile: eddie>
>>> author.is_adult()
True
原本你可能需要在View(Controller)層寫個if .. else ..來判斷,現在可以把這個判斷包在Model層裡,一來程式碼容易除錯,而且因為都集中在Model的話,萬一今天假設我們的法律把成年人條件改成滿20歲,你只要修改一下Model的邏輯判斷,其它程式碼不用修改就可以下班了,這樣感覺不是很歡樂嗎?
那個超佛心的管理後台呢?
記得我們在前面有提到Django有送我們一個很好用的後台管理系統嗎? 但那時候登入之後空空的什麼都沒有,接下來我們要來讓這個Profile類別在後台也可以管理。要讓Model在Admin模組可以看得到,有兩種做法,第一種是在App裡面新增一個admin.py,內容長得像這樣:
1 2 3 4 | |
這段程式碼的大意就是我們要把Profile類別給"註冊"到Admin模組裡,讓它也感覺得到它的存在。登入後台後,你應該可以看到Profile類別出現了:

你可以試著玩看看它的一些管理功能,試試從Admin模組去新增/修改/刪除/更新一些資料。除了剛剛在App裡新增admin.py之外,另一種做法就是把這個"註冊"的動作寫在Model裡,原來的Profile類別看起來會像這樣:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
兩種做法都可以,我個人比較偏第二種,因為可以少寫一個檔案(懶!),程式碼只要在Model找就行了。
到目前為止,我們很單純的都只有一個表格,但現實生活不可能有這麼美好的事,所以我們再來新增一些資料表,並且讓這些資料表彼此有一些關連。