星期二, 1月 30, 2007

Another Django Benchmark.

又一個新的web framework benchmark,
作的看起來似乎是目前所有benchmark評比裏面最完整的.
程式碼跟設定都有秀出來.
http://www.alrond.com/en/2007/jan/25/performance-test-of-6-leading-frameworks/

總而言之這次比了RubyOnRails,PHP的 CodeIgniter,Symfony,
Perl的Catalyst ,跟Python的 Django TurboGears

做出來的結果是:
django > turbogears=RoR1.1.6 > Catalyst > CodeIgniter > RoR 1.2.1 > Symfony (後面作者有補充, CodeIgniter加上eAccelerator似乎快了不少, 所以排名可能僅次於django, 只差一倍的效能.)

所以... 這次Django又在benchmark上贏了... :)

贏了其實也不是重點 重點是文章裏面有提到一些django的設定問題:
"""
The Prefork-mode takes away more memory,
but for it the system comes out, which stably works on extreme loads,
and the smaller use of the processor resources.
In a threaded-mode Django hanged under the big load and did not answer on inquiries.
The same happened with TurboGears too.
This is due to the fact that python works badly in a treaded-mode.
"""

這樣看來還是得把fastcgi啟動時的method改成非預設的prefork mode才可以.
(預設threaded大概是為了方便windows用戶吧?)

"""
Psyco module accelerates Django on 15-30 %,
but it will be worth the grown memory use VSZ on 80 % in a prefork-mode
and on 400 % (!!!) in threaded-mode. Use of RSS memory increases in 2-2.5 times.
"""
而且Psyco搭配django吃的memory在threaded-mode似乎也暴增?

再來還有更勁爆的... Psyco+ 64bit machine會運作的不大好!?

"""
About Psyco. Django-developers have tested it,
and have found something interesting.
On 32-bit systems it really gives an increase in productivity.
And on 64 bit - on the contrary productivity sinks.
It happens, because the processor switches under Psyco to a 32-bit mode
and does not use all advantages of one's own architecture.
If it is so, than this fact, that Django worked more quickly under Psyco,
very likely means,
that Linux and Python don't use 64 bits system (in spite of work on Overtone).
"""

總結這篇文章提到有關django的設定:
1. 在unix上使用fastcgi 時不要用預設的threaded mode, 要以prefork模式啟動.
2. 32位元機器而且有足夠的ram並且需要速度時可以使用psyco來換取速度.
3. 64位元機器或ram不大夠時(聽說ram永遠都不夠) 要斟酌使用psyco.


星期三, 1月 24, 2007

[tip] 透過django ORM轉換資料庫資料

之前剛好案子無預警的突然得從開發時採用的sqlite3轉成上線使用的postgresql,
那還好django的ORM是資料庫中立的, 不至於產生太大問題.
首先第一步當然是改settings.py之後syncdb把postgresql資料庫重新建立起來.
但是這樣一來舊有的資料就不見了.
要怎麼把舊的資料從sqlite3的資料庫轉到postgresql呢?

非到最後關頭請先不要急著寫SQL,
透過django的ORM轉換資料庫的舊資料其實簡單的多.
先將sqlite的資料透過cPickle作python object的serialization,
(文謅謅的, 其實就是把sqlite裡的資料存到硬碟成為python物件)
再透過新的設定值將物件讀回來,再存到postgresql裡.

一個重點是要記得QuerySet是Lazy evaluate的,
所以要加那個list()強迫evalutate, 否則資料會沒有真的存進去.

以下是我轉換的兩個範例script:
tran1.py:

from django.conf import settings
settings.configure(
DATABASE_ENGINE = 'sqlite3',
DATABASE_NAME = 'data.db'
)
from XXX.models import MMM

objs = list(MMM.objects.all ())
import cPickle
output = open('data.pkl', 'wb')
cPickle.dump(objs, output)
output.close()

tran2.py:

#!/usr/bin/python
from django.conf import settings
settings.configure (
DATABASE_ENGINE = 'postgresql',  
DATABASE_NAME = 'pserver',  
DATABASE_USER = 'django',
DATABASE_PASSWORD = 'abc',
DATABASE_HOST = 'localhost',
DATABASE_PORT = '5432'
)

from XXX.models import MMM
import cPickle
pkl_file = open('data.pkl', 'rb')
data1 = cPickle.load(pkl_file)
pkl_file.close()

[x.save() for x in data1 ]

我只轉換了一個table, 多個tables也只要如法泡製即可.
可能還有更簡單的方法, 不過對於我而言這樣就很夠了.

簡單擴充一下這個方法,
應該也可以套用在某些資料庫需要變更schema的情形而毋需撰寫SQL,
如果等不到django schema evolution的branch發展起來,
可以自己動手寫看看.

本blog即日起加入Unofficial Python@TW planet

經過kalug裡lloyd大大的提醒,
昨天mail給yungyuc大大, 在他的熱情幫忙之下,
本blog也於今日加入了Unofficial Python@TW planet的行列,
從今天起也可以在Planet上面看到本blog裡鬼扯Python跟Django的文章了,

如此本blog """以django攻略全世界,
用python同化藍星人."""的終極目標可說又是更進一步了.
實在是可喜可賀.

另外, 歡迎kalug裡django光明會支部的大家響應本blog
"""加入Unofficial Python@TW planet就是愛Python"""的活動
提早報名可早日修得Python正果~~

使徒提姆




星期一, 1月 22, 2007

kalug python講題的投影片

這邊有我之前在kalug講過的python投影片,
講題包括python modules, dynamic python 跟django.
投影片的格式是openoffice的odp.
請有興趣者自行下載.

django 0.95.1 released!

django 0.95.1 released!
http://www.djangoproject.com/weblog/2007/jan/21/0951/

主要是0.95的small security fix patch,
並未把svn的code引進來. (所以還是沒newform的)
建議所有目前還在跑0.95-django的系統升級.
(直接重安裝一次即可) svn的版本就不用了.

星期六, 1月 20, 2007

[想法] 以python+shedskin來取代shellscript-like的python程式.

前陣子有跟shedskin的作者通過幾次信,
(關於Shedskin請看我之前的介紹),
基本上目前作者認為Shedskin還有非常大幅度的改善空間,
他現在主要還是會把心力放在改善對python語法支持度的實作上,
不過他現在是全職進行開發, 看來shedskin仍是大有可為.

另外我也送了patch跟小tool過去,
所以現在shedskin也支援os.system()了,
還有一個簡單的小tool可以列出目前支援的function.
這樣可以幫助轉換只是使用python來作簡單的shell script應用的程式.

有機會的話我想要支援os.popen(), 其實popen()本身倒是不難,
只是pclose()的時機有一點麻煩, 畢竟C++沒有啥垃圾收集,
(雖然有libgc,但是libgc只管gc裡狹義的memory)
另外就是可能要改寫目前shedskin裡file object的行為會比較複雜,

我現在最初步的的作法是在os/__init__.cpp裡自行加入
file *_popen(str *c) {
return new file(popen(c->unit.c_str(),"r"));
}
等shedskin翻譯出來了之後, 再自行修改C++程式碼,
自己加入相對應的pclose(), 實在是很蠢的作法.

shedskin的作者有提到可以加一個
__os__::exit()的方向去想,
我在想應該可以把回傳的FILE* 當作static變數,
exit()時再close()掉,這倒似乎是一個可行的作法.
不過他也提到他對pipe沒啥好感,
看來他如果要作popen也會放在很後面才作了...

作者Mark感覺滿熱心的, 回的信比我寫給他的還多,
大家有興趣可以下載shedskin來玩玩,
即使只是bug report跟feedback 作者也會滿高興的.

pyjamas -- GWT in python

GWT 是google放出的一個完全僅撰寫java(不用寫任何一行javascript)
而進行ajax/javascript開發的一個工具組

pyjamas 則是模仿GWT的一個完全使用python進行ajax開發的一個工具



從SVN commit 進來之後

svn co http://svn.pyworks.org/svn/pyjamas/trunk/ pyjamas

cd pyjamas/examples

./buildall.sh 就可以將範例都編譯好


此時就可以直接將瀏覽器指向examples目錄來觀看各個範例的效果
老實說 雖然只要會python聽起來很酷 但是如果真的要使用 請考慮兩個問題:

1. pyjamas仍是成熟度不高的專案 如果有任何問題 你還是得自行動手使用javascript
2. 不懂javascript 而進行ajax/javascript開發經常是非常危險的
因為你很容易誤用了javascript而導致網頁更多的問題

另外, 網路上也有人寫了關於與Django一起用的應用
http://trac.pyworks.org/pyjamas/wiki/DjangoWithPyJamas

星期日, 1月 14, 2007

對於kalug的新首頁的想法

http://www.feedjack.org/

有鑑於kalug的wiki首頁老是被SPAM
(明明每次聚會都不少人,高手也不少,
但是現在看那個網頁感覺卻像是已經倒掉的社團一樣 :P)

上次有簡單跟黃大哥提過,
想把首頁改用feed aggregator的方式將kalug大家的blog都串連起來.
而django有一個Feedjack似乎有不少人使用,
下次聚會會跟大家討論一下使用這個的可行性跟大家的感覺.

我想稍微修改一下應該就可以整合一個wiki 系統,
讓wiki也能在同一個頁面使用才對.
(以方便我們的聚會通知 雖然通常都是第四個禮拜六下午啦 orz)

星期六, 1月 13, 2007

django blog裡一段有趣的評論

http://www.djangoproject.com/weblog/2007/jan/10/wired/

評論裡面在吵一堆關於admin介面的問題, 不過這段評論很好玩
Daniel Lathrop January 12, 2007
Maybe it's that easy things are SO easy in Django that people are surprised that hard things are still kinda hard. The other frameworks out there don't make easy things as easy as Django does (IMHO), so it's a smaller jump to the hard things in those because you're already having to muck around so much to accomplish anything.”

老實說我剛開始用Django的時候也有這麼一點想法:

(雖然很快就煙消雲散)

"""這不是Python寫的嗎 怎麼好像還有一點麻煩 ?"""

好像被Python的各種神奇library寵慣了,

一切東西到了python的環境都應該自動變簡潔十數倍以上才是 :P

httplib2.py

http://bitworking.org/projects/httplib2/

非常多人推薦的Python 3rd party Http library
比起官方的httplib 支援不少特色
(不知啥時才會被收到standard library)

http://bitworking.org/projects/httplib2/ref/module-httplib2.html

http://packages.debian.org/unstable/libs/python-httplib2

djangoid (django + openid)

http://trac.nicolast.be/djangoid/

話說現在blog界最紅的話題就是openid,

想裝作沒看到都很難 XD

而這個網址是opensource的Django架openid的Server,

熱血的Shawn同學如果有看到這篇的話(或是已經知道的話)...

這個就交給你實驗架在kalug上了啊... ^^

(話說回來.... 我不知不覺的就在Kalug server上裝好django環境了... XD)

(BTW, shorewall有空設一設吧

不好意思自己動手亂開port

shawn有讀到的話 開幾個大家來玩玩 :P )

ps: 對了 Sam ruby有一篇關於openid使用blog網址來轉址認證的

如果有興趣跟時間可以順便try一下

White Space in Languages

http://e-scribe.com/news/324

大家都知道Python有所謂的White Space Thingy,

這似乎造成了很多Python新手的困擾.

這個網址列出了幾個White space matters的Language

看來現在還真的有人用的只剩Python跟Haskell了

而在Haskell裡面 White Space Indent Style是選用的

所以只有Python真的是非用White Space不可.

這White Space Thingy呢

優點是讓Python程式清晰 結構簡單且容易閱讀

缺點是有時會造成一些小麻煩

(不過都是可以克服的

拜託別跟我扯lambda只能一行

高手請用你的lisp/Haskell吧)

要我說的話, 還是老話一句,

White Space Indent萬歲!!

Portable Python

http://www.portablepython.com/

(請注意這則消息是關於windows, linux/OSX/*BSD users請自動跳過)

要是你懶得看英文的話 請注意看關鍵字Django

看來All in one 的Django environment出現囉!

Portable Python is a Python® programming language preconfigured to run directly from a portable device, enabling you to have, at any time, a portable programming environment. One of the most powerful dynamic programming languages that is used in a wide variety of application domains and is used at many companies and institutions around the world (YouTube, Google, NASA, Firaxis Games, etc.).

Portable Python is distributed as a standalone zip file which contains complete latest Python® distribution for Windows together with a few help tools which will help you to run your python scripts from your portable device. So all you need to do is to download Portable Python zip file, extract it to your portable device and you are done! Everything is preconfigured so you can start working on your python application right away.

Python® is a programming language. It's used for many different applications. It's used in some high schools and colleges as an introductory programming language because Python® is easy to learn, but it's also used by professional software developers. Portable Python includes Django web application framework so you can build Web sites like this one!

What? Django? What's that? Well Django is a high-level web framework that eases the pain of building dynamic database-driven Web sites. It abstracts common problems of Web development and provides shortcuts for frequent programming tasks. Because Portable Python is based on Python® it includes SQLite database engine, that enables you to build database driven websites directly on your portable device and to develop everywhere!

Construct 2.0 released


http://construct.wikispaces.com/


比較值得注意的概念是Construct是declarative的

Construct
is a python library for parsing and building of data structures (binary or textual). It is based on the concept of defining data structures in a declarative manner, rather than procedural code: more complex constructs are composed of a hierarchy of simpler ones. It's the first library that makes parsing fun, instead of the usual headache it is today.

....

Unlike most other parsers, such as python's builtin struct module, Construct is declarative, can work with either bytes or single bits, follows pythonic paradigms, is easy to extend, and symmetrical. Apart from that, it comes loaded with built-in primitives, a tutorial, and an inventory of constructs for file formats and protocols.

Being declarative means you directly define the data structure, not the code that parses it. This means you can export your definition to XML, or write a code generator that takes a construct and converts it to a C module, just to name a few ideas.

Philosophy裡 這句Components are better than inheritance也深得我心

License: Public Domain

星期六, 1月 06, 2007

django svn, newforms and formtools

django svn比起django 0.95的版本
加入了newforms跟formtools這兩個新工具
在對html form的處理上有相當大的改進

不過大家要注意一個概念
不論是舊有的oldforms 或是新的工具
基本上這些都只是helper,
也就是方便大家處理form
並且提出一個django認為最佳的使用form的流程
讓即使是web 開發的新手
也能夠很快速的寫出一個專業而標準的web應用

但是就算沒透過這些工具,
只要能夠撰寫html碼 還是可以將這些form完成
並不是說django的newforms還沒開發完成
撰寫django的網頁便會有什麼問題,

畢竟一切還是以幫助你完成目前的手上工作為主.
即使沒有newforms和oldforms
直接手工打造form的html再加上
django本身所提供的其他功能就已經非常好用了.

newforms的說明已經有一些在django的官方document上了
不過還缺漏了不少部份 相信未來很快便能補齊
而到目前為止卻還完全沒有formtools的說明. (django book上有這個段落 不過尚未有說明)
formtools 是由adrian (django兩位核心開發者之一) 所開發的
根據adrian的 說法 , 並且我也實際玩了一下之後
發現其實newforms 主要是在規範form的結構跟validation
而formtools則是用來負責處理form的流程 兩者是互補的關係
也因此透過formtools跟newforms來搭配處理form必然會是未來django會經常使用到的開發form的方式.

由於目前還沒有正式的說明, 心急的話, 你可以馬上升級到django svn,並且直接閱讀原始碼裡的docstring
我有稍微玩過一下 的確新的方法比起舊的form處理方法是相當優雅方便的處理方式
等到未來帶有newforms跟formtools正式版本推出, django的開發相信會變的更迷人才是.

[小玩具] 使用ShedSkin轉換python成為C++

http://shed-skin.blogspot.com/

Shed Skin 是國外一套還在發展中的python->C++的編譯器
雖然目前的完成度不高(應該可以說幾乎還完全在實驗性的情況)
不過在現階段仍然可以利用python取代某些需要手寫C/C++語言
來獲得速度/執行檔空間縮小的情形

1. install shedskin (extract tarball and install its dependency)

2. get inside directory , and copy ss to your bin path

3. ss yourpyfile

4. make yourpyfile

到此就算完成了

5. ldd yourpyfile
linux-gate.so.1 => (0xffffe000)
libgc.so.1 => /usr/lib/libgc.so.1 (0xb7f69000)
libstdc++.so.6 => /usr/lib/gcc/i686-pc-linux-gnu
/4.1.1/libstdc++.so.6 (0xb7e8f000)
libm.so.6 => /lib/libm.so.6 (0xb7e6a000)
libgcc_s.so.1 =>
/usr/lib/gcc/i686-pc-linux-gnu/4.1.1/libgcc_s.so.1 (0xb7e60000)
libc.so.6 => /lib/libc.so.6 (0xb7d3d000)
libdl.so.2 => /lib/libdl.so.2 (0xb7d39000)
/lib/ld- linux.so.2 (0xb7fbe000)

值得注意的是編譯出來的執行檔會需要兩個dependency
一個是libstdc++ 另一個則是libgc
在大部分系統裡面 可能會沒有libgc.so
在某些更過分的系統裡面(連C++都沒有的環境是存在的 :( )
連libstdc++.so都沒有
不過倒是可以不必用-static 連glibc都一起編進去
我們有辦法只擺脫這兩個dependency
以下就是擺脫的方法:

(follows are how we get rid of libgc libgcc_s and libstdc++.so )
(warn: your C++ code can't use dynamic feature )
(see

http://www.trilithium.com/johan/2005/06/static-libstdc/ for more info)

6. ln -s `g++ -print-file-name=libstdc++.a`

7. ss yourpyfile.py

8. edit Makefile
replace top 5 lines to (warn: replace tmp/shedskin- 0.0.16 to your
shedskin directory)
CC=g++
CCFLAGS= -static-libgcc -O3 -L . -I/tmp/shedskin- 0.0.16/lib -L
/usr/lib/libgc.a
LFLAGS = /usr/lib/libgc.a

9. make yourpyfile

10. ldd yourpyfile
linux-gate.so.1 => (0xffffe000)
libm.so.6 => /lib/libm.so.6 (0xb7f70000)
libc.so.6 => /lib/libc.so.6 (0xb7e4e000)
/lib/ld-linux.so.2 (0xb7fbe000)

現在我們就獲得一個看起來完全像是C原生程式的執行檔囉! (而確實也是)
不包含libstdc++的helloworld類型的程式大約在150k左右
在妳包含了libstdc++之後大概會躍升到850k
所以要依造你所需求的環境自行選擇是否包含囉.

不過在此鄭重說明, 目前ShedSkin發展還在實驗階段
對於python內建模組的支援度是很少的 所以不要想透過ShedSkin撰寫複雜的程式
此外 由於python的語法實在過於動態
因此在寫要能讓ShedSkin翻譯的python程式時
要特別小心一些情形, 例如不要動態轉換型別 以及在container裡置入多種型別等.
否則ShedSkin是沒辦法處理的. (這些官方網站都有寫)

基本上我認為, 以目前Shedskin的發展狀況 只能夠作一些非常簡單的處理而已
(例如檔案或字串處理 不過基本上還是可以取代掉不少Shell在做的工作)
何況大部分不需要速度也不在乎執行檔/記憶體大小的情況則可以用pyinstaller或py2exe就可以讓對方不需要python直譯器也可以執行了.
所以其實真的沒什麼太大用途.
但是如果你真的需要速度 可是因為要處理的東西實在太簡單 又懶的重頭用C/C++ 開始寫
倒是可以先試試看將某部份先用python寫過 透過ShedSkin轉換成C++之後
再修改編譯出來的C++程式碼. (當然程式碼會變的很醜囉... :P)

星期一, 1月 01, 2007

[連結] Decorators make magic easy

http://www-128.ibm.com/developerworks/linux/library/l-cpdecor.html?ca=drs-

David Mertz, 著名的Charming Python系列作者的最新作品,
再度以這篇文章跟我們解釋了Decorators的用法.
由於Decorators大量的使用在Django中, 如果還沒有理解的,
這篇文章有非常多的解釋.

在Python2.4之前, 我們雖然經常使用decorator function,
但一直對Python沒有直接提供語法上的支援感到遺憾,
在Python 2.4中試圖引入了@這個decorator運算子,卻引起了大量的對於Python語法的爭議.
然而這段Decorator的語法爭議, 最後由Guido的仲裁中結束.

讓我簡單的說明的話,
decorator是用來讓function的logic能配合不同情況進行不同行為的一種方式,
而對於OOP語言來說, 這樣的技巧通常會使用meta class,
而對Python這種既支援functional programming又支援OOP的兼容性語言來說,
在很多狀況下, 無須使用meta programming,
而用decorator直接修改function是最方便的一種作法,
而django的每個view恰巧就是一個function,
所以如django的@login_required decorator就被大量的應用在django程式碼中.
這樣的decorator可以直接套用在有需要認證的view裡面, 無須對每個view分別修改其logic.

本文所提到的歷史部份可以參考:
http://www.python.org/cgi-bin/moinmoin/PythonDecorators

Guido對於@運算子的講解原文(僅供考古人士參考)

(tip) 利用Generic View來對Django裡的資料分頁

Django的Generic View是非常強大而具有彈性的功能,
基本上如果應用簡單的話,
妳甚至可以不用在views.py寫任何一行程式碼,
只單單在URLconf (urls.py)進行網址改寫便可以實作出你的view,
這一點, 在Django Tutorial Part4已有詳細的說明.

不過其實撰寫Python程式碼向來不會是什麼苦差事,
所以我們真正通常關心的是要如何擴充並在view裡使用Generic View的功能.
以下我就用分頁功能來做個說明:

先假設底下這段是我們原本的view:



@login_required
def stb_list_template_view(request):
stb_list = Stb.objects.filter(stbSubGroupNum__pGroup=request.session["pGroup"])
return render_to_response('stb_list.html',{'stb_list': stb_list,})


這是一段非常標準的未使用Generic View的處理方法,
我們從Stb中取出屬於pgroup的stb_list資料,
並將之傳送到stb_list.html這個template裡. 來看看我們怎麼對這段程式碼改寫,


@login_required
def stb_list_template_view(request):
from django.views.generic import list_detail

return list_detail.object_list(
request,
queryset = Stb.objects.filter(stbSubGroupNum__pGroup=request.seession["pGroup"]),
template_object_name = "stb",
template_name = "stblist.html",
allow_empty = True,
)



疑!? 怎麼程式碼看起來更冗長了?
別急別急, 這是因為我們原先的template並沒有使用到generic views規劃的預設名稱,
否則template_object_name跟template_name這兩個參數是可以省略的,
不過別忘了python的哲學就是Explict is better than implicit,
寫長一點對於其他對generic view似懂非懂的人更好維護.
此外, 如果你原先沒有使用generic view的想法,
也可利用這兩個參數對你原有的template作最小幅度的修改.

好了, 我們還沒有做到我們原先說要作的功能, 就是替這個Stb資料列表作分頁,
那要怎麼做呢? 啊, generic view已經幫我們想好了!
請加上粗體的這行:


@login_required
def stb_list_template_view(request):
from django.views.generic import list_detail

return list_detail.object_list(
request,

paginate_by = 10,

queryset = Stb.objects.filter(stbSubGroupNum__pGroup=request.seession["pGroup"]),
template_object_name = "stb",
template_name = "stblist.html",
allow_empty = True,
)

paginate_by = 10 這行表示每十筆資料分作一頁,
這樣就完成了! django的generic view會自動幫我們在每一個template裡面加入分頁所需的參數,
以下就是說明: (以下傳入參數的說明直接來自Django官方generic view說明文件)

* results_per_page: The number of objects per page. (Same as the paginate_by parameter.)
* has_next: A boolean representing whether there's a next page.
* has_previous: A boolean representing whether there's a previous page.
* page: The current page number, as an integer. This is 1-based.
* next: The next page number, as an integer. If there's no next page, this will still be an integer representing the theoretical next-page number. This is 1-based.
* previous: The previous page number, as an integer. This is 1-based.
* pages: The total number of pages, as an integer.
* hits: The total number of objects across all pages, not just this page.

你可以自行在template編排並使用這些參數來作出你想要的分頁樣式.
(是的, 這項是可以交給前端Web Designer作的工作,
不過如果案子小或有不可抗力因素, 你可以自己動手作)

而你也可透過修改Urlconf或直接使用網址的get參數來做修改,
例如: http://yourdomain.com/obj_list/?page=3
便可觀看第三頁的內容. 這些在Django的Generic View說明文件裡面都有解釋.

可是可是, 我們還想達到更強的功能, 那要怎麼做呢?
比如說, 我們希望在某分頁找不到時, 自動導向到沒有分頁的模式,
另外我們還想自己改變錯誤訊息(而非預設的404)的網頁,等等等等...
做得到嗎???

原始的generic view是做不到的,但是一切都是Python,我們只要進行改寫就可以了.
底下列出一段我應用在真實專案上的程式碼(略有修改):


@login_required
def stb_list_template_view(request):

#customize the paginate num
if 'paginate_by' in request.GET.keys():
paginate_by = int(request.GET.get('paginate_by', 1))
request.session['paginate_by'] = paginate_by
elif 'paginate_by' in request.session:
paginate_by = request.session['paginate_by']
else:
#default behavior
#you can turn off via set paginate_by = False
paginate_by = 10
queryset = Stb.objects.filter(stbSubGroupNum__pGroup=request.session["pGroup"])

from django.views.generic import list_detail
from django.core.paginator import ObjectPaginator, InvalidPage
try:
paginator = ObjectPaginator(queryset, paginate_by)
page = int(request.GET.get('page', 1))
object_list = paginator.get_page(page - 1)
except (InvalidPage, ValueError):
paginate_by = False
except:
problem = "page 404 problem!\n"+"\n".join(map(str,sys.exc_info()))
return HttpResponse(problem)
return list_detail.object_list(
request,
paginate_by = paginate_by,
queryset = queryset,
template_object_name = "stb", # default is object, context will
template_name = "stblist.html", # default name is Stb_list.html
allow_empty = True,
extra_context = {
'serverstat' : serverstat,
'session' : request.session,
})


這是Django的好處, 魔法很少, 一切都是我們熟知的Python.
只要我們需要, 隨時可以再花點精神擴充.

B-list上有一篇延伸閱讀文章, 可以一起讀一讀.