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 已發展成為一個通用的框架,能夠開發任何型別的網站。

目前還沒有一種現成且明確的伺服器端框架流行度的衡量標準(儘管您可以使用諸如統計每個平臺的 GitHub 專案數量和 StackOverflow 問題數量之類的機制來估計流行度)。一個更好的問題是 Django 是否“足夠流行”以避免不受歡迎平臺的問題。它是否在不斷發展?如果您需要幫助,您可以獲得幫助嗎?如果您學習 Django,您是否有機會獲得報酬的工作?

根據使用 Django 的知名網站數量、貢獻程式碼庫的人數以及提供免費和付費支援的人數,答案是肯定的,Django 是一個流行的框架!

使用 Django 的知名網站包括:Disqus、Instagram、Knight 基金會、MacArthur 基金會、Mozilla、國家地理、開放知識基金會、Pinterest 和 Open Stack(來源:Django 概述頁面)。

Django 有主見嗎?

Web 框架通常將自己稱為“有主見”或“無主見”。

有主見框架是指對處理任何特定任務的“正確方法”有主見的框架。它們通常支援 *在特定領域內* 的快速開發(解決特定型別的問題),因為做任何事情的正確方法通常是眾所周知且有據可查的。但是,它們在解決其主要領域之外的問題時可能不太靈活,並且往往為可以使用哪些元件和方法提供了更少的選擇。

相比之下,無主見框架對將元件組合在一起以實現目標的最佳方法,甚至對應該使用哪些元件,都有更少的限制。它們使開發人員更容易使用最合適的工具來完成特定任務,但代價是您需要自己找到這些元件。

Django 是“有點有主見”,因此它提供了“兩全其美”。它提供了一組元件來處理大多數 Web 開發任務,以及一種(或兩種)首選的使用方式。但是,Django 的解耦架構意味著您通常可以從許多不同的選項中進行選擇,或者根據需要新增對全新選項的支援。

Django 程式碼是什麼樣子的?

在傳統的以資料為中心的網站中,Web 應用程式會等待來自 Web 瀏覽器(或其他客戶端)的 HTTP 請求。當收到請求時,應用程式會根據 URL 和可能在 POST 資料或 GET 資料中的資訊來確定需要什麼。根據需要,它可能會從資料庫讀取或寫入資訊,或執行滿足請求所需的其他任務。然後,應用程式將向 Web 瀏覽器返回響應,通常透過將檢索到的資料插入 HTML 模板中的佔位符來動態建立 HTML 頁面供瀏覽器顯示。

Django Web 應用程式通常將處理每個步驟的程式碼分組到單獨的檔案中

Django - files for views, model, URLs, template

  • URLs:雖然可以透過單個函式處理來自每個 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 請求,則將呼叫關聯的檢視函式並將請求傳遞給它。

python
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 物件。在這種情況下,我們不會對請求做任何操作,我們的響應會返回一個硬編碼的字串。我們將在後面的章節中展示一個做更多有趣事情的請求。

python
# 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 就會為您處理所有與資料庫通訊的“髒活”。

下面的程式碼片段展示了一個非常簡單的 Django 模型,用於 Team 物件。Team 類是從 Django 類 models.Model 派生的。它定義了團隊名稱和團隊級別為字元欄位,並指定了要為每個記錄儲存的字元的最大數量。team_level 可以是多個值之一,因此我們將其定義為選擇欄位,並提供要在顯示時選擇的對映以及要儲存的資料,以及預設值。

python
# 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 用於搜尋關聯的資料庫。這可以匹配多個欄位,使用不同的條件(例如,精確匹配、不區分大小寫、大於等),並且可以支援複雜的語句(例如,您可以指定對 U11 團隊的搜尋,這些團隊的團隊名稱以“Fr”開頭或以“al”結尾)。

程式碼片段展示了一個用於顯示我們所有 U09 團隊的檢視函式(資源處理程式)。list_teams = Team.objects.filter(team_level__exact="U09") 行展示瞭如何使用模型查詢 API 過濾所有 team_level 欄位的值恰好為 'U09' 的記錄(注意這個條件是如何作為引數傳遞給 filter() 函式的,欄位名和匹配型別用雙下劃線分隔:team_level__exact)。

python
## 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 迴圈中迭代它。在每次迭代中,模板都會在 <li> 元素中顯示每個團隊的 team_name 值。

python
## 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 程式碼,但與客戶端程式碼不同,您需要設定一個開發環境才能執行它。這是我們的下一步。