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

URL 到處理函數(shù)的映射,就被稱為路由。Web 開發(fā)框架提供了路由配置的功能,可以方便的指定處理 URL 的函數(shù)。
4.2 模板渲染
用 Python 生成 HTML 的過程十分繁瑣,需要進(jìn)行字符串拼接,代碼的可讀性差。假設(shè),在一個(gè)學(xué)生管理系統(tǒng)中,有一個(gè)頁(yè)面是展示所有學(xué)生的姓名、學(xué)號(hào)等信息,Python 后端程序通過讀取數(shù)據(jù)庫(kù)生成一段 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>'
函數(shù) generateHtml() 通過 SQL 語(yǔ)句讀取數(shù)據(jù),使用字符串拼接成一段 HTML 的 table,返回給瀏覽器。這樣的方式的缺點(diǎn)在于:HTML 代碼和 Python 代碼混合在一起,程序的可讀性很差。
針對(duì)以上問題,提出了模板的解決方案,實(shí)現(xiàn)數(shù)據(jù)與 HTML 代碼分離。以下是使用 django 的模板實(shí)現(xiàn)展示所有的學(xué)生
<table>
{% for student in students %}
<tr>
<td>{{ student[0] }}</td>
<td>{{ student[1] }}</td>
</tr>
{% endfor %}
</table>
與拼接字符串相比,使用模板生成 HTML,顯著的提高了程序的可讀性,Web 框架都配備了各種模板引擎,Web 開發(fā)者需要學(xué)習(xí)模板的語(yǔ)法。
4.3 數(shù)據(jù)庫(kù) ORM
在 Web 開發(fā)中,需要訪問數(shù)據(jù)庫(kù)讀取相關(guān)數(shù)據(jù)返回給瀏覽器。通常是采用 SQL 語(yǔ)句訪問數(shù)據(jù)庫(kù),例如下面的 SQL 語(yǔ)句獲取 name 為張三的記錄:
SELECT name, age FROM persons WHERE name = '張三'
在程序中,使用 SQL 語(yǔ)句訪問數(shù)據(jù),易錯(cuò)、不夠直觀。因此有人提出了 ORM 技術(shù):把關(guān)系數(shù)據(jù)庫(kù)映射為對(duì)象。
面向?qū)ο缶幊毯完P(guān)系型數(shù)據(jù)庫(kù),都是目前最流行的技術(shù)。面向?qū)ο缶幊贪阉袑?shí)體看成對(duì)象(object),關(guān)系型數(shù)據(jù)庫(kù)則是采用實(shí)體之間的關(guān)系(relation)描述數(shù)據(jù)。
ORM (Object Relation Map) 是一種把關(guān)系數(shù)據(jù)庫(kù)映射成對(duì)象的技術(shù),下表總結(jié)兩者之間的對(duì)應(yīng)關(guān)系:
關(guān)系數(shù)據(jù)庫(kù) | 面向?qū)ο?/th> |
---|---|
數(shù)據(jù)庫(kù)的表(table) | 類(class) |
記錄(record,行數(shù)據(jù)) | 對(duì)象(object) |
字段(field) | 對(duì)象的屬性(attribute) |
Python 的 Web 框架通常提供了 ORM 的功能,用于簡(jiǎn)化對(duì)數(shù)據(jù)庫(kù)的訪問。