Python 領域運用:Web 開發
1. Web 開發簡介
1.1 Web 的歷史
1989年,TimBerner 提出了一種能讓遠隔兩地的研究者們共享知識的設想。它的基本理念是:借助多文檔之間相互關聯形成的超文本(HyperText),連成可相互參閱的 WWW(World Wide Web)。
在互聯網早期,網站的內容是靜態的,瀏覽相同地址的頁面返回的內容不會發生變化。由于網頁的內容是不發生變化的,因此早期互聯網站只能用于共享靜態的文檔,無法實現復雜的應用。
互聯網得到了飛速的發展,人們不再滿足網頁只有靜態文本的形式,出現了動態網頁的技術,例如專用于開發動態網頁的 PHP 編程語言。1995 年,Rasmus Lerdorf 發明了 PHP 編程語言。PHP 是在服務器端執行腳本語言,它動態生成 HTML 文本返回給瀏覽器。
1.2 出現了專門的 Web 開發工程師
在互聯網早期,網站中的主要內容由靜態頁面構成,開發一個網站并不需要太多的編程工作,網站開發人員會編寫 HTML 文件即可,很多網站甚至于不需要程序員的參與。
隨著互聯網的發展,網站的功能越來越復雜,網站提供的功能日趨豐富,網站更像是一個本地應用程序,而不是單純展示內容的網頁。在這個時期,開發 Web 需要編寫大量的程序,一個復雜的 Web 開發項目包含有數萬行、甚至于數十萬行的源代碼。
隨著網站開發的需求的增加,出現了專門的 Web 開發工程師,在計算機行業的招聘網站上搜索 "Web 開發”,可以獲得大量的職位招聘信息:
2. Web 開發入門
本節介紹進行 Web 開發所需要了解和掌握的技術。
2.1 HTML 基礎
HTML稱為超文本標記語言,是一種標識性的語言。它包括一系列標簽.通過這些標簽可以將網絡上的文檔格式統一,使分散的Internet資源連接為一個邏輯整體。HTML文本是由HTML命令組成的描述性文本,HTML命令可以說明文字,圖形、動畫、聲音、表格、鏈接等
HTML 不是一門編程語言,而是一種用于定義內容結構的標記語言。HTML 由一系列的元素(elements)組成,這些元素可以用來包圍不同部分的內容,使其以某種方式呈現或者工作。 一對標簽( tags)可以為一段文字或者一張圖片添加超鏈接,將文字設置為斜體,改變字號,等等。
學習 HTML 需要學習各種標簽,例如使用 table 標簽描述了一個 2 行 2 列的表格:
<table>
<tr>
<td>第 1 行 第 1 列</td>
<td>第 1 行 第 2 列</td>
</tr>
<tr>
<td>第 2 行 第 1 列</td>
<td>第 2 行 第 2 列</td>
</tr>
</table>
- table 標簽描述了一個表格
- tr 標簽描述表格中的一行
- td 標簽描述表格中的一個單元
第 1 行 第 1 列 | 第 1 行 第 2 列 |
第 2 行 第 1 列 | 第 2 行 第 2 列 |
2.2 CSS 基礎
層疊樣式表 (CSS) 是用來添加樣式到你網站的代碼。舉例來說,你想讓文字是黑色還是紅色的?在屏幕的何處展示內容?用什么背景圖像和顏色來裝飾你的網站?
和 HTML 類似,CSS 也不是真正的編程語言,甚至不是標記語言。它是一門樣式表語言,這也就是說人們可以用它來選擇性地為 HTML 元素添加樣式。舉例來說,要選擇一個 HTML 頁面里所有的段落元素,然后將其中的文本改成紅色,可以這樣寫 CSS:
p {
color: red
}
2.3 Javascript 基礎
JavaScript(縮寫:JS)是一門完備的 動態編程語言。當應用于 HTML 文檔時,可為網站提供動態交互特性。例如:檢查輸入的合法性、在按下按鈕或收到表單數據時做出的響應等。
JavaScript 的應用場合極其廣泛,簡單到響應按鈕點擊,復雜到游戲、2D/3D 動畫、大型數據庫驅動程序等等。
瀏覽器內置的 Javascript API 提供了豐富的功能,比如:動態創建 HTML 和設置 CSS 樣式、生成2D 圖像與音頻樣本等。
2.4 使用 Python 作為 Web 后端
使用瀏覽器訪問網站的過程如下所示:
- 瀏覽器向網站發出請求
- 網站收到請求后,返回 HTML 文本作為響應內容
在下圖的例子中,服務器返回當前時間 (HTML 的格式)。使用瀏覽器訪問網站時,顯示的內容是動態的,每次都是當前時間,如下所示:
在這個例子中,瀏覽器又被稱為前端,服務器又被稱為后端。后端收到請求后,做如下的工作:
- 分析用戶請求,獲取請求的參數
- 根據請求的參數進行處理,可能會讀取數據庫
- 最終生成一段 HTML 文本返回給前端
Python 作為一個通用的編程語言,能夠完成以上的工作,由于其開發效率高,在 Web 后端開發中占有重要的一席之地。以下是慕課網的課程分類目錄,在后端開發的分類中,Python 和 Django (Python 的 web 框架) 占有兩個條目:
3. Web 開發框架
3.1 簡介
在傳統的軟件開發中,框架是一種提供了可重用的公共結構的技術,為構建新的應用程序提供了極大的便利??蚣苁且环N非常成熟的技術,在多個領域得到了成功的應用,例如:在桌面應用程序開發的領域,微軟公司的 Visual Studio C++ 為應用程序生成框架,基于 VC++ 應用程序框架可以大大的提升桌面程序的開發效率。
隨著 Web 開發項目的復雜度的日益提升,軟件開發中的框架技術被引入到 Web 開發領域。Web 開發框架是用于進行 web 開發的一套軟件架構,Web 框架為 Web 應用程序提供了基礎的功能。開發人員在 Web 框架的基礎上實現自己的業務邏輯,基于 Web 框架開發應用,開發人員只需要專注應用的業務邏輯,非業務邏輯的基礎功能則由框架提供,從而提升開發效率。
3.2 常見的 Web 框架
目前,最流行的 Python 的 Web 開發框架是 Flask 框架和 Django 框架,截至 2019 年 9 月 2 日,Flask 在 Github 上的星數是 46179 顆,Django 的 Github 星數是 43806 顆,兩者幾乎難分伯仲,其它 Python Web 框架與 Flask 和 Django 星數相差甚遠。
兩者的主要區別在于:Django 功能大而全,Flask 只包含基本的功能。
Django 采用一站式解決的思路,Django 集成有模板、表單、路由、認證、基本的數據庫管理等內建功能,開發者不用在選擇應用的基礎設施上花費大量時間。
Django 就像是一個裝潢好的房子(如下圖所示),它提供了各種家具,直接入住即可。
Flask 相對于 Django 而言是輕量級的 Web 框架。和 Django 不同,Flask 只提供了最核心的功能,輕巧、簡潔,通過定制第三方擴展來實現具體功能。
默認情況下,不包含數據庫抽象、用戶認證、表單驗證、發送郵件等其它 Web 框架經常包含的功能。Flask依賴用各種靈活的擴展(比如郵件Flask Mail,用戶認證Flask Login,數據庫Flask SQLAlchemy)來給Web應用添加額外功能。
Flask 就像是一個沒有裝潢的房子(如下圖所示),用戶需要自己選擇各種家具才可以入住。
4. Web 框架提供的核心功能
4.1 路由配置
在 Web 開發過程中,經常會遇到 “路由” 的概念。簡單來說,路由就是 URL 到處理函數的映射。
Web 后端處理大致流程可以看成這樣:
- 瀏覽器發出請求
- 服務器端監聽到 80 端口的請求,解析請求的 url 路徑
- 根據服務器的路由配置,找到對應 url 對應的處理函數
- 運行處理函數生成一段 HTML 文本,并返回給瀏覽器
假設一個論壇系統由如下數據構成:
- 主題,每個主題包含有標題和內容,使用 topicID 標識該主題
- 用戶,每個用戶包含姓名和密碼,使用 userID 標識該用戶
論壇的域名是 www.bbs.com,它向外界提供了若干可訪問的 URL:
URL | 功能 |
---|---|
http://www.bbs.com/topics/12373 | 訪問 topicID 為 12373 的主題 |
http://www.bbs.com/users/1353 | 訪問 userID 為 1353 的用戶頁面 |
在服務器端有兩個處理頁面函數:
- showTopic(topicId) 顯示指定 topicId 的主題內容
- showUser(userId) 顯示指定 userId 的用戶信息
在下圖中,當用戶請求形式為 /topics/xxx 的 URL 時,服務器需要找到 showTopic 函數處理該請求;當用戶請求形式為 /users/xxx 的 URL 時,服務器需要找到 showUser 函數處理該請求。

URL 到處理函數的映射,就被稱為路由。Web 開發框架提供了路由配置的功能,可以方便的指定處理 URL 的函數。
4.2 模板渲染
用 Python 生成 HTML 的過程十分繁瑣,需要進行字符串拼接,代碼的可讀性差。假設,在一個學生管理系統中,有一個頁面是展示所有學生的姓名、學號等信息,Python 后端程序通過讀取數據庫生成一段 HTML 文本,代碼如下:
def generateHtml():
html = ''
html += '<table>'
sql = 'SELECT * FROM students'
cursor.execute(sql)
students = cursor.fetchall()
for student in students:
html += '<tr>'
html += '<td>%s</td>' % student[0]
html += '<td>%s</td>' % student[1]
html += '</tr>'
html += '<table>'
函數 generateHtml() 通過 SQL 語句讀取數據,使用字符串拼接成一段 HTML 的 table,返回給瀏覽器。這樣的方式的缺點在于:HTML 代碼和 Python 代碼混合在一起,程序的可讀性很差。
針對以上問題,提出了模板的解決方案,實現數據與 HTML 代碼分離。以下是使用 django 的模板實現展示所有的學生
<table>
{% for student in students %}
<tr>
<td>{{ student[0] }}</td>
<td>{{ student[1] }}</td>
</tr>
{% endfor %}
</table>
與拼接字符串相比,使用模板生成 HTML,顯著的提高了程序的可讀性,Web 框架都配備了各種模板引擎,Web 開發者需要學習模板的語法。
4.3 數據庫 ORM
在 Web 開發中,需要訪問數據庫讀取相關數據返回給瀏覽器。通常是采用 SQL 語句訪問數據庫,例如下面的 SQL 語句獲取 name 為張三的記錄:
SELECT name, age FROM persons WHERE name = '張三'
在程序中,使用 SQL 語句訪問數據,易錯、不夠直觀。因此有人提出了 ORM 技術:把關系數據庫映射為對象。
面向對象編程和關系型數據庫,都是目前最流行的技術。面向對象編程把所有實體看成對象(object),關系型數據庫則是采用實體之間的關系(relation)描述數據。
ORM (Object Relation Map) 是一種把關系數據庫映射成對象的技術,下表總結兩者之間的對應關系:
關系數據庫 | 面向對象 |
---|---|
數據庫的表(table) | 類(class) |
記錄(record,行數據) | 對象(object) |
字段(field) | 對象的屬性(attribute) |
Python 的 Web 框架通常提供了 ORM 的功能,用于簡化對數據庫的訪問。