啓動輕量級 Django

啓動輕量級 Django

起步

相比 fastapi、flask 等 http 框架,django 一直被 python 程序員認爲**“重”**。“重”有很多理解方式,我至少認爲它不是在指責 django 大而全——由於自己多才多藝而被嫌棄,django 豈不是很冤?!所以我理解的、普遍意義的“重”是:django 總要給我提供我不需要的東西

在我看來,django-admin startprojectdjango-admin startapp 絕對是萬惡之源。命令末尾一回車,我需要的不需要的都來了,項目的目錄結構也被死死釘住。所以長期以來我對 django 絕無任何好感。直到一次在推特上表達心聲,有個大佬對我的言論充滿鄙夷,一來二去的交鋒,最後被他推薦去看《Lightweight Django》。

我一直以來認爲用 django 寫 demo 是挺煩人的,但《Lightweight Django》的作者卻說:不用麻煩了。

如果是 flask

flask 長期以來作爲 django 的競爭對手,並以“輕”著稱,那麼先來看看 flask 如何啓動一個 web 服務。

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "hello world"

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8000, debug=True)

很簡潔是不是?但這只是“縮寫”而已。一旦我們要寫一個正常一點的項目,就算是規模小一些,用“縮寫”就不夠用了。比方說響應頭的 header 設置,比方說路由的模塊劃分。所以實際項目中,flask 的代碼組織結構大概率呈現如下方式:

import os

# 環境變量
debug = os.environ.get("debug", "on") == "on"

from flask import Flask, make_response

app = Flask(__name__)
# 配置信息
app.config.update(
    debug=debug,
)

# 視圖函數
def index():
    response = make_response("hello world")
    return response

# 註冊路由
app.add_url_rule("/", None, index)

if __name__ == "__main__":
    # 啓動程序
    app.run(host="127.0.0.1", port=8000)

(註冊路由不再用裝飾器,僅僅是我個人愛好而已)

也就是說,一個 http 服務至少是需要配置信息視圖函數註冊路由三部分;爲了能跟 uwsgi 通信,我們還需要 application,好巧不巧,app = Flask(__name__) 語句中的 app 就是那個我們要的 application;最後是啓動服務的 app.run()

請記住這個結構,接下來我們就用 django 來實現。

輕量級 django

首先來完成視圖函數,這稍微簡單些:

from django.http import HttpResponse

def index(request):
    response = HttpResponse("hello world")
    return response

與 flask 稍稍不同,django 要求視圖函數默認接收一個 request 參數。

接着是路由。django 中,路由的“註冊”方式是靜態的,因爲它不是去註冊,而是以配置的方式添加路由:

from django.conf.urls import url

# urlpatterns 是默認變量
urlpatterns = (
    url("^$", index),
)

但是現在對 django 來說,它還找不到路由。django 是自己去註冊路由,而你需要告訴它路由文件在哪兒。**“告訴”**這個動作需要在配置信息里弄。所以正好把 django 的配置信息方式說了。

import os
# 環境變量
debug = os.environ.get("debug", "on") == "on"

from django.conf import settings
settings.configure(
    DEBUG=debug,
    ROOT_URLCONF=__name__,  # 告訴 django, 配置路由的文件在哪兒
)

現在完成了配置信息視圖函數註冊路由三部分,我們還需要通信的 application。

from django.core.wsgi import get_wsgi_application

application = get_wsgi_application()

最後是啓動服務。你有兩種方式,一種是選擇python xxx.py runserver,另一種是python xxx.py。爲了對標 flask,這裏就選擇實現後者:

from django.core.management import execute_from_command_line
execute_from_command_line([__name__, "runserver"])

事實上,我們已經完成了一個輕量級的 django http 服務。完整代碼如下:

import os
from django.http import HttpResponse
from django.conf.urls import url
from django.conf import settings
from django.core.wsgi import get_wsgi_application

# 環境變量
debug = os.environ.get("debug", "on") == "on"

settings.configure(
    DEBUG=debug,
    ROOT_URLCONF=__name__,
)

# 視圖函數
def index(request):
    response = HttpResponse("hello world")
    return response

# 註冊路由
urlpatterns = (
    url("^$", index),
)

application = get_wsgi_application()

if __name__ == "__main__":
    # 啓動程序
    from django.core.management import execute_from_command_line
    execute_from_command_line([__name__, "runserver"])

總結

認真說起來,輕量級的 django 還是比 flask 麻煩一點點,尤其導包太多(不失尷尬的微笑)。但通過學習啓動輕量級 django,大致明白了 django-admin startproject 生成的內容都有什麼用,也可以自己掌握代碼的目錄結構啦,以後就不會糊里糊塗覺得 django “重” 了。

參考

  • 《Lightweight Django - The World’s Smallest Django Project》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章