上節知悉了 django
是如何作到自動重啓的以後,那麼接下來了解下它是如何運行起一個 web 服務的。python
很熟悉的命令web
經過下面的命令,咱們即可將 django 跑起來。那麼它發生了什麼呢?django
python3 manage.py runserver
瀏覽器
在此以前,根據 django 運行的服務,咱們也利用 wsgiref 這個模塊實現一個簡單的 web 服務。網絡
# server_demo.py
from wsgiref.simple_server import WSGIServer, WSGIRequestHandler
def demo_app(environ, start_response):
from io import StringIO
stdout = StringIO()
print("Hello world!", file=stdout)
print(file=stdout)
h = sorted(environ.items())
for k, v in h:
print(k, '=', repr(v), file=stdout)
start_response("200 OK", [('Content-Type', 'text/plain; charset=utf-8')])
return [stdout.getvalue().encode("utf-8")]
s = WSGIServer(("127.0.0.1", 1234), WSGIRequestHandler)
# 設置應用,注意了這裏不必定非是個函數,但是一切可調用的對象
# 例如 函數、方法、類或實現了 __call__ 方法的實例
s.set_app(demo_app)
# 開始監聽請求,這裏應該是用的 poll 或者 selector 的網絡模型。
s.serve_forever()
複製代碼
運行起來 server_demo.py
這個文件,而後經過瀏覽器訪問 127.0.0.1:1234
,會發現頁面響應了一堆內容(沒必要關心展現的內容具體是什麼)。app
接下來觀察源碼。socket
django/core/servers/basehttp.py 下的 run 方法函數
def run(addr, port, wsgi_handler, ipv6=False, threading=False, server_cls=WSGIServer):
server_address = (addr, port)
if threading:
httpd_cls = type('WSGIServer', (socketserver.ThreadingMixIn, server_cls), {})
else:
httpd_cls = server_cls
httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6)
if threading:
httpd.daemon_threads = True
# 這裏的 wsgi_handler 來自於
# from django.core.handlers.wsgi import WSGIHandler
httpd.set_app(wsgi_handler)
httpd.serve_forever()
複製代碼
這是一個 wsgi 應用,它被定義在了 proj/wsgi.py
下的 application
屬性。(application
對應剛剛上面代碼中出現的 wsgi_handler
)spa
application
這個屬性對應的是個 get_wsgi_application
函數,該函數調用的過程當中,針對 django.core.handlers.wsgi.WSGIHandler
這個類進行了實例化,在 __init__
方法中,加載了 django
中間件。code
# django.core.handlers.wsgi.py
class WSGIHandler(base.BaseHandler):
request_class = WSGIRequest
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 載入中間件(注意:這裏很關鍵。)
self.load_middleware()
複製代碼
至此,咱們瞭解到了 django 的服務是從 django/core/servers/basehttp.py
下的 run
方法啓動了一個 wsgi
服務。這個可調用的對象來自於 django.core.handlers.wsgi.WSGIHandler
,這個類在實例化(__init__
)的過程當中,加載了中間件。
咱們也更應該瞭解下 wsgi
。