Django 其內部已經自帶了一個方便本地測試的小服務器, 因此在剛開始學習 Django 的時候並不需搭建 apache 或者 nginx 服務器. Django 自帶的服務器基於 python wsgiref 模塊實現的, 其百分之七八十的代碼都是 wsgiref 中的代碼, 只重寫了一部分, 因此 Django 自帶的服務器測試寫個 helloworld 就行了.python
Django 內置服務器在 django.core.servers 和 django.core.handlers, 這二者共同來實現.先看看 django.core.servers. 下面是目錄結構:nginx
E:\DECODE-DJANGO\DJANGO-1.5.1\DJANGO\CORE\SERVERS
basehttp.py 重寫 ServerHandler,WSGIServer,WSGIRequestHandler,定義 run() 函數
fastcgi.py
__init__.pygit
下面的代碼足以說明「百分之七八十」:github
class ServerHandler(simple_server.ServerHandler, object): ... class WSGIServer(simple_server.WSGIServer, object): ... class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
具體內部作了一些變動:apache
都是無關痛癢, 不詳細展開了.這裏定義了一個頗有意思的函數 run():django
def run(addr, port, wsgi_handler, ipv6=False, threading=False): server_address = (addr, port) if threading: httpd_cls = type(str('WSGIServer'), (socketserver.ThreadingMixIn, WSGIServer), {}) else: httpd_cls = WSGIServer httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6) httpd.set_app(wsgi_handler) httpd.serve_forever() 永久運行
這和上一篇 if __name__ == '__main__': 中的代碼效果相似, 實例化服務器類, 讓它跑起來. 在 run() 函數中能夠根據喜愛配置:服務器
add: 地址, 可傳入 ip 地址, 通常是 127.0.0.1多線程
port: 端口, 自定義端口app
wsgi_handler: 上節提到的 application, 在 django.core.handlers 中定義socket
ipv6: 若是爲 true, 會將協議地址族換成是 AF_INET6
threading: 若是爲 true, 服務器會被強制成 type(str('WSGIServer'), (socketserver.ThreadingMixIn, WSGIServer), {})(這個我漏講了, 但功能是這樣), 能處理多線程處理請求.
因此, 調用這個函數能夠讓一個自定義服務器跑起來.
wsgi_handler 參數定義了 application, 而 application 必須是一個 start_response(status, response_headers, exc_info=None) 形式的函數或者定義了 __call__ 的類. 而 django.core.handlers 就用後一種方式實現了 application.
E:\DECODE-DJANGO\DJANGO-1.5.1\DJANGO\CORE\HANDLERS
base.py application 的基類 BaseHandler
wsgi.py 實現 WSGIHandler 類, 定義了 __call__, 這樣就名正言順的 WSGI 中的 application 了
__init__.py
事實上, 在 WSGI 中除了 application,server 外, 還有一個 middleware, 名曰中間件. 在上一篇中故意漏了, 由於沒有涉及到.最後我疏離一下上邊提到的類模塊等等, 方便你們找源碼, 整理以下:
C:\PYTHON27\LIB\WSGIREF
handlers.py 定義了 BaseHandler, SimpleHandler 類
headers.py
simple_server.py 定義了 ServerHandler, WSGIRequestHandler 類, demo_app(), make_server()
util.py
validate.py
__init__.pyE:\DECODE-DJANGO\DJANGO-1.5.1\DJANGO\CORE\SERVERS
basehttp.py 重寫 ServerHandler,WSGIServer,WSGIRequestHandler,定義 run() 函數
fastcgi.py
__init__.pyE:\DECODE-DJANGO\DJANGO-1.5.1\DJANGO\CORE\HANDLERS
base.py application 的基類 BaseHandler
wsgi.py 實現 WSGIHandler 類, 定義了 __call__, 這樣就名正言順的 WSGI 中的 application 了
__init__.py
ps: 目錄根據實際狀況會不一樣, 看具體狀況.我已經在 github 備份了 Django 源碼的註釋: Decode-Django, 有興趣的童鞋 fork 吧.
搗亂 2013-9-6