設計理念¶
本文說明 Django 開發人員在建立框架時所採用的一些基本理念。其目標是解釋過去並引導未來。
整體¶
鬆散耦合¶
Django 堆疊的基本目標是鬆散耦合和緊密內聚。框架的各個層級不應「知道」彼此,除非絕對必要。
例如,範本系統不了解 Web 請求,資料庫層不了解資料顯示,而視圖系統不關心程式設計師使用哪個範本系統。
雖然 Django 為了方便起見提供完整的堆疊,但堆疊的各個部分在可能的情況下都是彼此獨立的。
更少的程式碼¶
Django 應用程式應盡可能使用最少的程式碼;它們應該缺乏樣板程式碼。Django 應充分利用 Python 的動態功能,例如內省。
快速開發¶
在 21 世紀,Web 框架的重點是讓 Web 開發中繁瑣的方面變得快速。Django 應該允許極快的 Web 開發。
不要重複自己 (DRY)¶
每個不同的概念和/或資料片段都應存在於一個且只有一個地方。重複是不好的。標準化是好的。
在合理的範圍內,框架應從盡可能少的資訊中推斷出盡可能多的資訊。
另請參閱
顯式優於隱式¶
這是 PEP 20 中列出的核心 Python 原則,這表示 Django 不應執行太多「魔法」。除非有非常好的理由,否則不應發生魔法。只有當魔法可以創造其他方式無法達成的巨大便利性時,才值得使用魔法,而且其實作方式不會讓試圖學習如何使用該功能的開發人員感到困惑。
一致性¶
框架應在所有層級保持一致。一致性適用於從低層級(使用的 Python 編碼樣式)到高層級(使用 Django 的「體驗」)的所有內容。
模型¶
顯式優於隱式¶
欄位不應僅根據欄位名稱來假設某些行為。這需要太多系統知識,而且容易出錯。相反,行為應基於關鍵字引數,在某些情況下,則基於欄位的類型。
包含所有相關的網域邏輯¶
模型應遵循 Martin Fowler 的 Active Record 設計模式,封裝「物件」的每個面向。
這就是為什麼由模型表示的資料和有關它的資訊(其人類可讀的名稱、預設排序等選項)都在模型類別中定義;理解給定模型所需的所有資訊都應儲存在模型中。
資料庫 API¶
資料庫 API 的核心目標是
SQL 效率¶
它應盡可能少次執行 SQL 陳述式,並應在內部最佳化陳述式。
這就是為什麼開發人員需要明確呼叫 save()
,而不是框架在幕後默默儲存內容的原因。
這也是為什麼存在 select_related()
QuerySet
方法的原因。它是針對選取「每個相關物件」的常見案例的可選效能提升工具。
簡潔、強大的語法¶
資料庫 API 應允許以盡可能少的語法編寫豐富、富有表現力的陳述式。它不應依賴匯入其他模組或輔助物件。
如有必要,應在幕後自動執行聯結。
每個物件都應該能夠存取系統中的每個相關物件。此存取應雙向運作。
需要時輕鬆切換至原始 SQL 的選項¶
資料庫 API 應意識到它是一個捷徑,但不一定是終極目標。框架應讓編寫自訂 SQL 變得容易,包括完整的陳述式,或只是作為 API 呼叫的自訂參數的自訂 WHERE
子句。
URL 設計¶
鬆散耦合¶
Django 應用程式中的 URL 不應與底層 Python 程式碼耦合。將 URL 與 Python 函數名稱連結在一起是一件糟糕且醜陋的事情。
按照這些思路,Django URL 系統應允許同一應用程式的 URL 在不同的情境中有所不同。例如,一個網站可能會將故事放在 /stories/
,而另一個網站可能會使用 /news/
。
無限的彈性¶
URL 應盡可能靈活。應允許任何可想見的 URL 設計。
鼓勵最佳實務¶
框架應讓開發人員設計美觀的 URL 與醜陋的 URL 一樣容易(甚至更容易)。
應避免在網頁 URL 中使用副檔名。
URL 中使用小插曲風格的逗號應受到嚴厲懲罰。
明確的 URL¶
從技術上講,foo.com/bar
和 foo.com/bar/
是兩個不同的 URL,搜尋引擎機器人(和一些 Web 流量分析工具)會將它們視為不同的頁面。Django 應盡力「正規化」URL,使搜尋引擎機器人不會感到困惑。
這是 APPEND_SLASH
設定背後的理由。
範本系統¶
將邏輯與呈現分開¶
我們將範本系統視為一個控制呈現和與呈現相關的邏輯的工具,僅此而已。範本系統不應支援超出此基本目標的功能。
不鼓勵重複¶
大多數動態網站都使用某種常見的網站設計,包括常見的頁首、頁尾、導覽列等。Django 範本系統應讓您可以輕鬆地將這些元素儲存在單一位置,從而消除重複的程式碼。
這是 範本繼承背後的理念。
與 HTML 解耦¶
範本系統的設計不應僅輸出 HTML。它應該同樣擅長產生其他基於文字的格式,或只是純文字。
XML 不應用於範本語言¶
使用 XML 引擎剖析範本會在編輯範本時引入全新的人為錯誤,並在範本處理中產生無法接受的額外負荷。
假設設計師具有能力¶
範本系統的設計不應讓範本必須在 Dreamweaver 等 WYSIWYG 編輯器中完美顯示。這是一個過於嚴格的限制,而且會使語法不夠美觀。Django 期望範本作者可以輕鬆地直接編輯 HTML。
明顯地處理空格¶
範本系統不應對空格執行任何魔法操作。如果範本包含空格,系統應將空格視為文字來處理,直接顯示它。任何不在範本標籤中的空格都應顯示。
不要發明程式語言¶
目標不是發明程式語言。目標是提供足夠的程式設計式功能,例如分支和迴圈,這對於制定與呈現相關的決策至關重要。Django 範本語言 (DTL) 的目標是避免進階邏輯。
安全與保障¶
範本系統應禁止包含惡意程式碼(例如刪除資料庫記錄的命令)。
這是範本系統不允許使用任意 Python 程式碼的另一個原因。
可擴充性¶
範本系統應認識到進階範本作者可能希望擴充其技術。
這是自訂範本標籤和篩選器背後的理念。
視圖¶
簡單性¶
編寫視圖應像編寫 Python 函數一樣簡單。當函數可以完成時,開發人員不應實例化類別。
使用請求物件¶
視圖應能存取請求物件 – 一個儲存目前請求相關元數據的物件。該物件應直接傳遞給視圖函數,而不是讓視圖函數從全域變數存取請求資料。這樣可以使視圖輕巧、乾淨,並且可以透過傳入「偽造」的請求物件來輕鬆測試視圖。
鬆散耦合¶
視圖不應關心開發人員使用哪個模板系統,甚至是否使用模板系統。
區分 GET 和 POST¶
GET 和 POST 是不同的;開發人員應明確使用其中一個。框架應使區分 GET 和 POST 資料變得容易。
快取框架¶
Django 的 快取框架 的核心目標是
更少的程式碼¶
快取應盡可能快。因此,所有圍繞快取後端的框架程式碼都應保持在絕對最小值,尤其是對於 get()
操作。
一致性¶
快取 API 應在不同的快取後端之間提供一致的介面。
可擴展性¶
快取 API 應在應用程式層級上根據開發人員的需求進行擴展(例如,請參閱 快取鍵轉換)。