Django 介紹
在這篇關於 Django 的首篇文章中,我們將回答“Django 是什麼?”這個問題,並概述這個 Web 框架的獨特之處。
我們將概述其主要特性,包括一些在本模組中我們沒有時間詳細介紹的高階功能。我們還將向您展示 Django 應用程式的一些主要構建塊(儘管此時您還沒有可供測試的開發環境)。
| 預備知識 | 對伺服器端網站程式設計,特別是網站中客戶端-伺服器互動機制的總體理解。 |
|---|---|
| 目標 | 熟悉 Django 是什麼、它提供了哪些功能以及 Django 應用程式的主要構建塊。 |
Django 是什麼?
Django 是一個高階 Python Web 框架,可以實現安全且可維護網站的快速開發。由經驗豐富的開發人員構建,Django 解決了 Web 開發中的大部分繁瑣工作,因此您可以專注於編寫應用程式,而無需重複造輪子。它是免費和開源的,擁有一個蓬勃發展的活躍社群,出色的文件,以及許多免費和付費支援選項。
Django 幫助您編寫的軟體具備以下特點:
- 完整
-
Django 遵循“內含電池”的理念,幾乎提供了開發人員“開箱即用”所需的一切。因為您需要的一切都是同一“產品”的一部分,所以它們無縫協作,遵循一致的設計原則,並擁有廣泛且最新的文件。
- 多功能
-
Django 可以(並且已經)用於構建幾乎任何型別的網站——從內容管理系統和維基,到社交網路和新聞網站。它可以與任何客戶端框架一起工作,並可以以幾乎任何格式(包括 HTML、RSS 提要、JSON 和 XML)提供內容。
在內部,雖然它為幾乎所有您可能需要的功能提供了選擇(例如,幾個流行的資料庫、模板引擎等),但如果需要,它也可以擴充套件以使用其他元件。
- 安全
-
Django 透過提供一個旨在“正確行事”以自動保護網站的框架,幫助開發人員避免許多常見的安全錯誤。例如,Django 提供了一種安全的方式來管理使用者帳戶和密碼,避免了將會話資訊放入容易受到攻擊的 Cookie 中(相反,Cookie 只包含一個金鑰,實際資料儲存在資料庫中)或直接儲存密碼而不是密碼雜湊等常見錯誤。
密碼雜湊是透過將密碼傳送到加密雜湊函式建立的固定長度值。Django 可以透過執行雜湊函式並將其輸出與儲存的雜湊值進行比較來檢查輸入的密碼是否正確。但是,由於該函式的“單向”特性,即使儲存的雜湊值被洩露,攻擊者也很難推斷出原始密碼。
Django 預設提供對許多漏洞的保護,包括 SQL 注入、跨站指令碼、跨站請求偽造和點選劫持(有關此類攻擊的更多詳細資訊,請參閱網站安全)。
- 可伸縮
-
Django 使用基於元件的“無共享”架構(架構的每個部分都獨立於其他部分,因此可以在需要時替換或更改)。不同部分之間清晰的分離意味著它可以透過在任何級別新增硬體來擴充套件以應對增加的流量:快取伺服器、資料庫伺服器或應用程式伺服器。一些最繁忙的站點已成功擴充套件 Django 以滿足其需求(例如,Instagram 和 Disqus,僅舉兩例)。
- 可維護
-
Django 程式碼是使用鼓勵建立可維護和可重用程式碼的設計原則和模式編寫的。特別是,它利用了“不重複自己”(DRY)原則,因此沒有不必要的重複,從而減少了程式碼量。Django 還提倡將相關功能分組到可重用的“應用程式”中,並在更低的級別上,將相關程式碼分組到模組中(遵循模型-檢視-控制器 (MVC) 模式)。
- 可移植
-
Django 是用 Python 編寫的,Python 可以在許多平臺上執行。這意味著您不受任何特定伺服器平臺的限制,可以在多種 Linux、Windows 和 macOS 版本上執行您的應用程式。此外,Django 得到了許多 Web 主機提供商的良好支援,他們通常為託管 Django 站點提供特定的基礎設施和文件。
它從何而來?
Django 最初由一個負責建立和維護報紙網站的 Web 團隊在 2003 年至 2005 年間開發。在建立了許多網站之後,該團隊開始提取和重用許多通用程式碼和設計模式。這些通用程式碼演變為一個通用的 Web 開發框架,並於 2005 年 7 月作為“Django”專案開源。
Django 不斷發展和改進,從 2008 年 9 月的第一個里程碑版本 (1.0) 到 2023 年底的 5.0 版本。每個版本都增加了新功能和錯誤修復,從支援新型資料庫、模板引擎和快取,到新增“通用”檢視函式和類(這減少了開發人員在許多程式設計任務中必須編寫的程式碼量)。
注意:檢視 Django 網站上的釋出說明,瞭解最新版本中的變化,以及為使 Django 變得更好所做的工作量。
Django 現在是一個蓬勃發展的、協作式的開源專案,擁有數以千計的使用者和貢獻者。雖然它仍然保留了一些反映其起源的特性,但 Django 已經發展成為一個多功能框架,能夠開發任何型別的網站。
Django 有多受歡迎?
沒有現成且明確的伺服器端框架流行度衡量標準(儘管您可以使用計算每個平臺的 GitHub 專案數量和 Stack Overflow 問題數量等機制來估計流行度)。一個更好的問題是 Django 是否“足夠流行”以避免不受歡迎平臺的問題。它是否還在不斷發展?如果您需要幫助,能得到嗎?如果您學習 Django,是否有機會獲得有償工作?
根據使用 Django 的知名網站數量、程式碼庫貢獻者數量以及提供免費和付費支援的人數,是的,Django 是一個流行的框架!
使用 Django 的知名網站包括:Disqus、Instagram、Knight Foundation、MacArthur Foundation、Mozilla、National Geographic、Open Knowledge Foundation、Pinterest 和 Open Stack(來源:Django 概覽頁面)。
Django 是有主見的嗎?
Web 框架通常將自己稱為“有主見的”或“無主見的”。
有主見的框架是對如何處理任何特定任務有“正確方法”的框架。它們通常支援特定領域(解決特定型別問題)的快速開發,因為做任何事情的正確方法通常是眾所周知且有詳細文件的。然而,它們在解決其主要領域之外的問題時靈活性較差,並且傾向於提供較少的元件和方法選擇。
相比之下,無主見的框架對如何將元件組合起來以實現目標,甚至應該使用哪些元件,限制要少得多。它們使開發人員更容易使用最合適的工具來完成特定任務,儘管代價是您需要自己找到這些元件。
Django 是“有點主見的”,因此它提供了“兩全其美”的優點。它提供了一組元件來處理大多數 Web 開發任務,以及一種(或兩種)首選的使用方式。然而,Django 的解耦架構意味著您通常可以從許多不同的選項中進行選擇,或者如果需要,可以新增對全新選項的支援。
Django 程式碼是什麼樣子的?
在傳統的基於資料的網站中,Web 應用程式等待來自 Web 瀏覽器(或其他客戶端)的 HTTP 請求。當收到請求時,應用程式會根據 URL 以及 POST 資料或 GET 資料中的資訊來確定所需的內容。根據所需內容,它可能會從資料庫中讀取或寫入資訊,或執行滿足請求所需的其他任務。然後,應用程式會向 Web 瀏覽器返回響應,通常透過將檢索到的資料插入到 HTML 模板中的佔位符來動態建立要由瀏覽器顯示的 HTML 頁面。
Django Web 應用程式通常將處理每個步驟的程式碼分組到單獨的檔案中

- URL: 雖然可以透過單個函式處理每個 URL 的請求,但編寫一個單獨的檢視函式來處理每個資源更易於維護。URL 對映器用於根據請求 URL 將 HTTP 請求重定向到適當的檢視。URL 對映器還可以匹配 URL 中出現的特定字串或數字模式,並將這些作為資料傳遞給檢視函式。
- 檢視: 檢視是一個請求處理函式,它接收 HTTP 請求並返回 HTTP 響應。檢視透過模型訪問滿足請求所需的資料,並將響應的格式化委託給模板。
- 模型: 模型是 Python 物件,它定義了應用程式資料結構,並提供了管理(新增、修改、刪除)和查詢資料庫中記錄的機制。
- 模板: 模板是定義檔案(如 HTML 頁面)結構或佈局的文字檔案,其中包含用於表示實際內容的佔位符。檢視可以使用 HTML 模板動態建立 HTML 頁面,並用來自模型的資料填充它。模板可以用於定義任何型別檔案的結構;它不一定是 HTML!
注意: Django 將這種組織方式稱為“模型-檢視-模板 (MVT)”架構。它與更熟悉的模型-檢視-控制器架構有許多相似之處。
下面的部分將讓您瞭解 Django 應用程式這些主要部分的樣子(我們將在課程後期,設定好開發環境後,詳細介紹)。
將請求傳送到正確的檢視 (urls.py)
URL 對映器通常儲存在名為 urls.py 的檔案中。在下面的示例中,對映器 (urlpatterns) 定義了路由(特定的 URL 模式)和相應檢視函式之間的一系列對映。如果收到與指定模式匹配的 URL 的 HTTP 請求,則將呼叫關聯的檢視函式並傳遞請求。
urlpatterns = [
path('admin/', admin.site.urls),
path('book/<int:id>/', views.book_detail, name='book_detail'),
path('catalog/', include('catalog.urls')),
re_path(r'^([0-9]+)/$', views.best),
]
urlpatterns 物件是 path() 和/或 re_path() 函式的列表(Python 列表使用方括號定義,其中專案用逗號分隔,並且可能有一個可選的尾隨逗號。例如:[item1, item2, item3,])。
這兩種方法的第一個引數是要匹配的路由(模式)。path() 方法使用尖括號定義 URL 中將被捕獲並作為命名引數傳遞給檢視函式的部分。re_path() 函式使用一種靈活的模式匹配方法,稱為正則表示式。我們將在後面的文章中討論這些!
第二個引數是模式匹配時將呼叫的另一個函式。符號 views.book_detail 表示該函式名為 book_detail(),並且可以在名為 views 的模組中找到(即,在一個名為 views.py 的檔案中)。
處理請求 (views.py)
檢視是 Web 應用程式的核心,它接收來自 Web 客戶端的 HTTP 請求並返回 HTTP 響應。在此期間,它們排程框架的其他資源來訪問資料庫、渲染模板等。
下面的示例展示了一個最小的檢視函式 index(),它可能由我們上一節中的 URL 對映器呼叫。像所有檢視函式一樣,它接收一個 HttpRequest 物件作為引數 (request) 並返回一個 HttpResponse 物件。在這種情況下,我們不對請求做任何操作,並且我們的響應返回一個硬編碼的字串。我們將在後面的部分中向您展示一個執行更有趣操作的請求。
# filename: views.py (Django view functions)
from django.http import HttpResponse
def index(request):
# Get an HttpRequest - the request parameter
# perform operations using information from the request.
# Return HttpResponse
return HttpResponse('Hello from Django!')
注意:一點 Python 知識
- Python 模組是函式的“庫”,儲存在單獨的檔案中,我們可能希望在程式碼中使用它們。這裡我們只從
django.http模組匯入HttpResponse物件,以便我們可以在檢視中使用它:from django.http import HttpResponse。還有其他方法可以匯入模組中的部分或所有物件。 - 函式使用
def關鍵字宣告,如上所示,函式名稱後括號中列出了命名引數;整行以冒號結尾。請注意,接下來的行都是縮排的。縮排很重要,因為它指定了程式碼行位於該特定塊中(強制縮排是 Python 的一個關鍵特性,也是 Python 程式碼如此易讀的一個原因)。
檢視通常儲存在名為 views.py 的檔案中。
定義資料模型 (models.py)
Django Web 應用程式透過稱為模型的 Python 物件管理和查詢資料。模型定義了儲存資料的結構,包括欄位型別,還可能包括它們的最大大小、預設值、選擇列表選項、文件幫助文字、表單標籤文字等。模型的定義獨立於底層資料庫——您可以在專案設定中選擇其中一個。一旦您選擇了要使用的資料庫,您就不需要直接與它通訊——您只需編寫模型結構和其他程式碼,Django 會為您處理所有與資料庫通訊的“髒活”。
下面的程式碼片段展示了一個用於 Team 物件的非常簡單的 Django 模型。Team 類派生自 Django 類 models.Model。它將團隊名稱和團隊級別定義為字元欄位,並指定每個記錄要儲存的最大字元數。team_level 可以是多個值中的一個,因此我們將其定義為選擇欄位,並提供要顯示的選擇和要儲存的資料之間的對映,以及一個預設值。
# filename: models.py
from django.db import models
class Team(models.Model):
team_name = models.CharField(max_length=40)
TEAM_LEVELS = (
('U09', 'Under 09s'),
('U10', 'Under 10s'),
('U11', 'Under 11s'),
# …
# list other team levels
)
team_level = models.CharField(max_length=3, choices=TEAM_LEVELS, default='U11')
注意:一點 Python 知識
Python 支援“面向物件程式設計”,這是一種將程式碼組織成物件的程式設計風格,其中包括相關資料和操作該資料的函式。物件還可以繼承/擴充套件/派生自其他物件,允許相關物件之間共享通用行為。在 Python 中,我們使用關鍵字 class 來定義物件的“藍圖”。我們可以根據類中的模型建立多種特定型別的物件例項。
因此,例如,這裡我們有一個 Team 類,它派生自 Model 類。這意味著它是一個模型,並將包含模型的所有方法,但我們也可以賦予它自己的特殊功能。在我們的模型中,我們定義了資料庫需要儲存我們資料所需的欄位,並給它們指定了特定的名稱。Django 使用這些定義,包括欄位名稱,來建立底層資料庫。
查詢資料 (views.py)
Django 模型提供了一個簡單的查詢 API,用於搜尋關聯的資料庫。它可以同時使用不同的條件(例如,精確匹配、不區分大小寫、大於等)匹配多個欄位,並支援複雜的語句(例如,您可以指定搜尋以“Fr”開頭或以“al”結尾的 U11 團隊)。
程式碼片段顯示了一個檢視函式(資源處理程式),用於顯示我們所有的 U09 團隊。list_teams = Team.objects.filter(team_level__exact="U09") 行顯示了我們如何使用模型查詢 API 過濾所有 team_level 欄位完全包含文字 U09 的記錄(請注意,此條件如何作為引數傳遞給 filter() 函式,其中欄位名和匹配型別由雙下劃線分隔:team_level__exact)。
## filename: views.py
from django.shortcuts import render
from .models import Team
def index(request):
list_teams = Team.objects.filter(team_level__exact="U09")
context = {'youngest_teams': list_teams}
return render(request, '/best/index.html', context)
此函式使用 render() 函式建立傳送回瀏覽器的 HttpResponse。此函式是一個快捷方式;它透過組合指定的 HTML 模板和要插入模板的一些資料(在名為 context 的變數中提供)來建立 HTML 檔案。在下一節中,我們將展示模板如何插入資料以建立 HTML。
渲染資料(HTML 模板)
模板系統允許您指定輸出文件的結構,使用佔位符來表示在生成頁面時將填充的資料。模板通常用於建立 HTML,但也可以建立其他型別的文件。Django 開箱即用支援其原生模板系統和另一個流行的 Python 庫 Jinja2(如果需要,它也可以支援其他系統)。
程式碼片段顯示了上一節中 render() 函式呼叫的 HTML 模板可能的樣子。此模板是在假定它在渲染時將訪問一個名為 youngest_teams 的列表變數的情況下編寫的(此變數包含在上面 render() 函式中的 context 變數中)。在 HTML 骨架內部,我們有一個表示式,它首先檢查 youngest_teams 變數是否存在,然後在一個 for 迴圈中迭代它。在每次迭代中,模板將每個團隊的 team_name 值顯示在一個 元素中。<li>
## filename: best/templates/best/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Home page</title>
</head>
<body>
{% if youngest_teams %}
<ul>
{% for team in youngest_teams %}
<li>{{ team.team_name }}</li>
{% endfor %}
</ul>
{% else %}
<p>No teams are available.</p>
{% endif %}
</body>
</html>
您還能做什麼?
前面的部分展示了您幾乎在每個 Web 應用程式中都會使用的主要功能:URL 對映、檢視、模型和模板。Django 提供的其他功能包括:
- 表單:HTML 表單用於收集使用者資料以在伺服器上進行處理。Django 簡化了表單的建立、驗證和處理。
- 使用者認證和許可權:Django 包含一個強大的使用者認證和許可權系統,該系統在設計時就考慮到了安全性。
- 快取:動態建立內容比提供靜態內容計算強度更大(也更慢)。Django 提供了靈活的快取,因此您可以儲存渲染頁面的全部或部分,以便除了必要時才重新渲染。
- 管理站點:當您使用基本骨架建立應用程式時,Django 管理站點預設包含在內。它使站點管理員可以非常輕鬆地提供管理頁面來建立、編輯和檢視站點中的任何資料模型。
- 資料序列化:Django 使您能夠輕鬆地將資料序列化並以 XML 或 JSON 格式提供。這在建立 Web 服務(一個純粹向其他應用程式或站點提供資料而不顯示任何內容的網站)或建立客戶端程式碼處理所有資料渲染的網站時非常有用。
總結
恭喜,您已完成 Django 之旅的第一步!您現在應該瞭解 Django 的主要優勢、其歷史以及 Django 應用程式主要部分的粗略樣子。您還應該學習了一些關於 Python 程式語言的知識,包括列表、函式和類的語法。
您已經看到了一些實際的 Django 程式碼,但與客戶端程式碼不同,您需要設定開發環境才能執行它。那是我們的下一步。