1. 概述
本書是基于Django和Python網(wǎng)站開發(fā)的實(shí)戰(zhàn)型手冊(cè)。本書主要是為初學(xué)者設(shè)計(jì)的,希望為初學(xué)者提供一個(gè)如何使用Django 2.0開發(fā)一個(gè)網(wǎng)站應(yīng)用的含有詳細(xì)步驟的攻略教程。
本書旨在對(duì)Django官方以及其他優(yōu)秀的網(wǎng)上教程進(jìn)行補(bǔ)充。通過將所有的內(nèi)容整合在一起,實(shí)戰(zhàn)開發(fā)的方法學(xué)習(xí)如何正確使用Django 2.0框架, 同時(shí)填補(bǔ)了不少官方文檔中的坑。此外,本書還介紹了一些在網(wǎng)絡(luò)應(yīng)用開發(fā)中需要用到的其他的知識(shí)(例如,HTML、CSS、JavaScript 等等)。
1.1 為什么使用本書學(xué)習(xí)
本書能節(jié)約你的時(shí)間 我們經(jīng)常能見到很多十分聰明的學(xué)生在學(xué)習(xí)Django和其他相關(guān)的網(wǎng)站應(yīng)用開發(fā)工具時(shí),耗費(fèi)了大量的精力和時(shí)間,依然被卡在某個(gè)環(huán)節(jié)。其原因往往是因?yàn)槟硞€(gè)關(guān)鍵知識(shí)點(diǎn)沒有提供支持信息,或者說明的不夠清晰。偶爾情況下,這樣的問題會(huì)耽誤你學(xué)習(xí)工作10-15分鐘,更多時(shí)候解決這些問題需要耗費(fèi)數(shù)個(gè)小時(shí)。我們?cè)噲D盡可能的掃除這些障礙,幫助你盡快的投入到應(yīng)用開發(fā)中,而不是泥足深陷在這些坑里。
本書能降低你的學(xué)習(xí)曲線 當(dāng)然應(yīng)用程序框架(Django)可以幫助你減少大量的麻煩和時(shí)間,前提是你必須準(zhǔn)確知道如何使用他們!但是通常情況下,相關(guān)知識(shí)的學(xué)習(xí)曲線是非常陡峭。本書嘗試著解釋清楚如何將所有的知識(shí)整合在一起,從而幫助你能快速前進(jìn)。
本書能提升你的工作流程 使用應(yīng)用程序框架要求遵循特定的設(shè)計(jì)模式,所以這也要求需要將特定的代碼塊放入特定的位置。在和很多初學(xué)者一起工作以后,我們聽到很多關(guān)于使用框架的抱怨,特別是如何擺脫框架的控制(即反轉(zhuǎn)控制),我們創(chuàng)造了很多工作流來幫助你更好的聚焦在開發(fā)過程,這樣你就能重新獲得控制感,并更有規(guī)則的構(gòu)建的網(wǎng)站應(yīng)用。
本書不是用來閱讀的 你可以按照你的設(shè)想做所有的事情,但是請(qǐng)不要僅僅閱讀本書!這是一本教你如何動(dòng)手用Django開發(fā)應(yīng)用的指導(dǎo)書,閱讀不是上手做。只有跟隨本書真正動(dòng)手完成開發(fā)了這個(gè)應(yīng)用,你才能從練習(xí)中收獲得更多。但是在你為這個(gè)應(yīng)用實(shí)際編寫代碼的時(shí)候,請(qǐng)不要 復(fù)制黏貼 書中的代碼。請(qǐng)手動(dòng)輸入每一行代碼,思考每一行代碼的作用,并閱讀本書中所為你提供的相關(guān)解釋,如果你依然無法理解,你可以嘗試使用Stack Overflow或者其他有用的網(wǎng)站來幫助你解決問題,這樣你才能彌補(bǔ)你知識(shí)中的不足。當(dāng)然當(dāng)你發(fā)現(xiàn)你無法跨過這道坎的時(shí)候,你也可以聯(lián)系我們,這樣我們可以更好的更新我們的資源,其實(shí)我們獲得了許多其他讀者的幫助和反饋。
1.2 你能從本書中學(xué)到什么
在本書中,我們將使用案例教學(xué)的方法,本書將會(huì)一步一步教你如何構(gòu)建一個(gè)名叫 Rango (請(qǐng)查閱1.4 項(xiàng)目設(shè)計(jì)簡述)的網(wǎng)站應(yīng)用程序。在這個(gè)學(xué)習(xí)過程中,我們將向你展示如何完成以下關(guān)鍵性任務(wù)。
- 如何配置你的開發(fā)環(huán)境 ——包括如何使用 終端,虛擬環(huán)境,pip 安裝程序,以及如何使用 Git 等等
- 安裝Django項(xiàng)目 以及如何創(chuàng)建一個(gè)基礎(chǔ)的Django項(xiàng)目
- 配置Django項(xiàng)目 來支持靜態(tài)媒體及其他媒體文件
- 創(chuàng)建數(shù)據(jù)庫模型 使用Django所提供的對(duì)象關(guān)系映射(ORM)功能
- 創(chuàng)建表單 這樣你就能利用數(shù)據(jù)庫模型來動(dòng)態(tài)生成你的網(wǎng)站頁面
- 使用Django提供的 用戶驗(yàn)證(user Authentication) 功能模塊
- 將 外部服務(wù)(external services) 整合進(jìn)你的Django項(xiàng)目中去
- 在你的網(wǎng)站應(yīng)用中使用 層疊樣式表(CSS) 和 JavaScript
- 讓你應(yīng)用中所使用的 CSS 顯的更專業(yè)
- 在Django中使用 Session 和 cookie
- 在你的應(yīng)用中使用更高級(jí)的內(nèi)容,例如 AJAX
- 使用 PythonAnyWhere 在網(wǎng)站服務(wù)器上 部署你的應(yīng)用
在每一章的結(jié)尾處,我們提供了一些具有挑戰(zhàn)性的練習(xí),在讓你更深入思考的同時(shí),讓你了解自己是否已經(jīng)掌握了剛才所學(xué)的內(nèi)容。本書的后面幾章還提供了一些開放性的開發(fā)練習(xí),同時(shí)包含了相應(yīng)的解決方案和思路。
練習(xí): 所有練習(xí)都會(huì)以這樣的方式清晰展示
在每一個(gè)單元我們都已經(jīng)添加了一些練習(xí)來測試你是否已經(jīng)掌握了知識(shí)點(diǎn)和相關(guān)技能。
你需要認(rèn)真的完成這些練習(xí),因?yàn)楹罄m(xù)的章節(jié)能否很好的理解,依賴于這些知識(shí)和技能的掌握。
假如你在某個(gè)問題商卡住了,也請(qǐng)不要擔(dān)心,你可以直接查詢我們的 Github 代碼庫,來尋找問題的答案。
1.3 相關(guān)技術(shù)和功能包
在本書的教程中,我們將會(huì)涉及以下的技術(shù)和外部功能服務(wù)包。
- Python 編程語言
- Pip 包管理
- Django
- Git 版本控制
- Github
- HTML
- CSS
- JavaScript
- JQuery 庫
- Twitter Bootstrap 前端框架
- Webhose API 搜索接口
- PythonAnyWhere 主機(jī)部署服務(wù)
我們選擇這些技術(shù)不僅僅是因?yàn)檫@些技術(shù)是網(wǎng)站應(yīng)用開發(fā)的基礎(chǔ),而且為我們提供了很好的例子來向你展示,如何集成類似 Bootstrap 的CSS工具組件,類似 Webhose API 的第三方服務(wù)包,以及如何使用 PythonAnyWhere 來快速部署你的網(wǎng)站應(yīng)用。
1.4 Rango: 初始設(shè)計(jì)以及功能定義
在本書中,我們將會(huì)聚焦在如何開發(fā)一個(gè)應(yīng)用,名叫 Rango 。 我們?cè)陂_發(fā)這個(gè)應(yīng)用的過程中,將會(huì)學(xué)習(xí)到將來開發(fā)任何網(wǎng)站應(yīng)用都會(huì)用到的核心組件。要想查看這個(gè)應(yīng)用的完整功能,請(qǐng)?jiān)L問 How to Tango with Django 網(wǎng)站。
設(shè)計(jì)概述
現(xiàn)在你的客戶向你提出了一個(gè)需求,需要?jiǎng)?chuàng)建一個(gè)名叫 Rango 的網(wǎng)站。在這個(gè)網(wǎng)站上可以讓用戶通過用戶定義的多個(gè)目錄訪問相對(duì)應(yīng)的不同網(wǎng)站頁面。在西班牙問中,rango 的意思是“質(zhì)量排名協(xié)會(huì)“或者“社會(huì)階層的位置“
- 在 Rango 的主頁 main page ,你的客戶希望用戶能看到:
- 前 5 個(gè)瀏覽最多的頁面
- 前 5 個(gè)瀏覽最多(或者打分最多)的目錄
- 為訪問者提供瀏覽和檢索目錄的功能
- 當(dāng)用戶瀏覽 目錄頁面 category page 的時(shí)候,你的客戶希望 Rango可以顯示:
- 當(dāng)前 目錄的名稱,訪問數(shù)量, 喜歡數(shù)量, 以及和當(dāng)前目錄相關(guān)的頁面列表(顯示頁面名稱,以及超鏈接到頁面內(nèi)的地址)
- 以及提供搜索功能(通過搜索API)查詢其他可以被加入當(dāng)前目錄的頁面。
- 在特定的目錄中,客戶希望:可以記錄目錄的名字, 每個(gè)目錄頁面的被訪問次數(shù),以及 多少用戶點(diǎn)擊了喜歡 (即,頁面被打分)。
- 每個(gè)目錄需要可以通過具有可讀性的地址進(jìn)行訪問,例如
/rango/books-aboutdjango/ - 只有 注冊(cè)用戶才能在目錄中添加和搜索頁面, 因此訪客可以自己注冊(cè)賬戶。
一眼看去,這個(gè)應(yīng)用的開發(fā)似乎非常簡單,本質(zhì)上這就是一個(gè)網(wǎng)頁鏈接分類目錄的列表系統(tǒng),但是,這個(gè)項(xiàng)目中還是有不少復(fù)雜的具有挑戰(zhàn)的知識(shí)點(diǎn)需要我們關(guān)注的。首先讓我們通過一些頂層設(shè)計(jì),看看到底我們?cè)陧?xiàng)目中需要開發(fā)哪些細(xì)節(jié)。
練習(xí):
在展開進(jìn)一步工作之前,先讓我們考慮一下以上對(duì)項(xiàng)目的需求定義,并做一些設(shè)計(jì)草案。
- N層(N-Tier)和系統(tǒng)結(jié)構(gòu)圖(System Architecture diagram)
- 首頁和目錄頁的線框圖(Wireframes)
- 本應(yīng)用的一系列地址映射(URL Mappings)
- 用來描述我們需要實(shí)現(xiàn)的數(shù)據(jù)模型的實(shí)體關(guān)系(ER)圖
在學(xué)習(xí)下面環(huán)節(jié)之前,請(qǐng)嘗試著先完成這些練習(xí),即使你并不了解系統(tǒng)結(jié)構(gòu)圖,線框圖或者實(shí)體關(guān)系圖,那就請(qǐng)考慮一下你該如何解釋和描述哪些你準(zhǔn)備開發(fā)的東西呢?
N層結(jié)構(gòu) N-Tier Architecture
大多數(shù)網(wǎng)站應(yīng)用的高層級(jí)結(jié)構(gòu)使用的是3層結(jié)構(gòu)。但是 Rango 需要和第三方服務(wù)做接口,所以它的層次結(jié)構(gòu)是一個(gè)非標(biāo)準(zhǔn)的變體。

由于我們是使用Django來構(gòu)建我們的網(wǎng)站應(yīng)用,我們將會(huì)使用以下的技術(shù)來實(shí)現(xiàn)各個(gè)層次:
- 客戶端(client) 網(wǎng)頁瀏覽器(例如 Chrome, Safari, Firefox),負(fù)責(zé)對(duì) HTML/CSS 頁面進(jìn)行渲染
- 中間層(middleware) 是 Django 應(yīng)用,在我們開發(fā)的時(shí)候,將會(huì)使用Django網(wǎng)頁服務(wù)器作為任務(wù)調(diào)撥
- 數(shù)據(jù)庫(database) 使用基于Python的 SQLite3 數(shù)據(jù)庫引擎
- 搜索接口(Search API) 就是搜索接口
在大部分的情況下,我們將會(huì)聚焦在如何開發(fā)中間層,但是很顯然從系統(tǒng)結(jié)構(gòu)圖來看,我們要考慮所有的組件并與所有其他組件接口
線框圖
向客戶展現(xiàn)最終項(xiàng)目完成時(shí)的界面,線框圖是一個(gè)很好的方法。它能節(jié)約大量的時(shí)間,并且你可以根據(jù)你所掌握的工具,選擇向客戶提供簡單手繪草圖,或是高精度仿制模型。對(duì)于我們的Rango應(yīng)用來說,我們希望我們的首頁和目錄頁能與下面的截圖一致。


頁面和地址映射 URL Mapping
根據(jù)需求定義,我們已經(jīng)在我們的應(yīng)用內(nèi)確定了兩個(gè)需要在不同的訪問位置下向用戶展現(xiàn)的頁面。我們需要描述清楚 URL地址,用來讓用戶訪問不同的頁面。地址映射就是用戶在瀏覽器地址欄中輸入的地址文本,來瀏覽指定的頁面。Rango的基礎(chǔ)URL 地址映射如下。
- 用
/或者/rango/來訪問首頁(入口頁) -
/rango/about/指向關(guān)于頁 -
/rango/category/<category-name>/,將會(huì)指向<category-name>所對(duì)應(yīng)的目錄頁,它的值可能是會(huì)是:- games;
- python-recipes;
- code-and-compilers。
在構(gòu)建我們的應(yīng)用的時(shí)候,我們很可能需要?jiǎng)?chuàng)建其他的URL地址映射。但是上述所列的可以給我們一個(gè)起點(diǎn),并且在我們創(chuàng)建其他頁面的時(shí)候提供很好的思路。同時(shí),隨著本書逐步學(xué)習(xí),我們將會(huì)使用Django框架和 模型-視圖-視圖模版 的設(shè)計(jì)思路來充實(shí)我們構(gòu)建這些頁面的方法。我們現(xiàn)在已經(jīng)有了URL地址映射的關(guān)鍵點(diǎn),以及頁面未來的樣子,現(xiàn)在我們要開始定義為我們的應(yīng)用存儲(chǔ)和提供數(shù)據(jù)的數(shù)據(jù)模型了。
實(shí)體關(guān)系圖(ER圖)
根據(jù)需求定義,很顯然我們至少需要兩個(gè)實(shí)體:category 和 page , 并且一個(gè) category 可以容納許多個(gè) page。以此我們可以用以下的ER圖來表示簡單的數(shù)據(jù)模型。

需要留意的是,這里有一些需求定義并不是很清晰,理論上來說一個(gè) page 應(yīng)該可以屬于1個(gè)或者多個(gè) category 。如果要滿足這個(gè)需求,那么我們需要定義 category 和 page 為多對(duì)多的關(guān)系。然而這樣的化,會(huì)讓項(xiàng)目復(fù)雜很多,所以為了簡化項(xiàng)目,我們?cè)谶@里設(shè)定:一個(gè) category 可以包含多個(gè) page,但是一個(gè) page 只能屬于一個(gè) category 。其實(shí)這個(gè)并不影響一個(gè)頁面需要存在于多個(gè)目錄下這個(gè)功能,只是這個(gè)頁面需要在數(shù)據(jù)庫中建立多個(gè)記錄,當(dāng)然這個(gè)解決方案是有瑕疵的。
做好筆記
養(yǎng)成記錄你曾做過的所有設(shè)定的習(xí)慣,就像我們現(xiàn)在設(shè)定的一對(duì)多的實(shí)體關(guān)系一樣。你永遠(yuǎn)都不知道你做的設(shè)定會(huì)給你埋下多大的坑。記錄下來,這讓你可以通過于你開發(fā)團(tuán)隊(duì)成員之間的溝通來確保,你所做的設(shè)定是明智,所有人都可以在這個(gè)設(shè)定下進(jìn)行工作。
依據(jù)這個(gè)設(shè)定,我們做了一些表格來描述各個(gè)實(shí)體的細(xì)節(jié)。這些表格說明了各個(gè)實(shí)體都擁有哪些字段。我們使用了Django的 ModelField 類型來定義各個(gè)字段的類型(即 CharField, IntegerField, URLField 以及 ForeignKey),請(qǐng)留意在Django中 主鍵 primary keys 是隱式的,以便 Django向每個(gè)模型添加了id,我們會(huì)在后面的 數(shù)據(jù)庫和模型 章節(jié)深入討論。
Category 模型
| Field | Type |
|---|---|
| name | CharField |
| views | IntegerField |
| likes | IntegerField |
Page 模型
| Field | Type |
|---|---|
| category | ForeignKey |
| title | CharField |
| url | URLField |
| views | IntegerField |
我們還需要有個(gè) User 的模型,這樣用戶才能注冊(cè)和登陸。我們現(xiàn)在不做討論,但是會(huì)在用戶驗(yàn)證部分進(jìn)行介紹。在后續(xù)章節(jié)中,我們將會(huì)展示如何在 Django 中實(shí)例化這些模型,同時(shí)如何使用內(nèi)建的 ORM 連結(jié)數(shù)據(jù)庫。
1.5 總結(jié)
這些頂層設(shè)計(jì)和需求規(guī)范將會(huì)為我們的網(wǎng)站應(yīng)用開發(fā)建立非常良好的參考點(diǎn)。雖然我們將主要關(guān)注如何使用特定的技術(shù),但是這些方法在絕大部分?jǐn)?shù)據(jù)庫驅(qū)動(dòng)的網(wǎng)站中都是非常常見的。所以熟悉如何閱讀和制作這些需求規(guī)范和設(shè)計(jì)文檔,能幫助你更好的和其他人溝通你的想法和設(shè)計(jì),這是十分重要和有幫助的。在這里,我們將使用 Django 以及相關(guān)的技術(shù)來實(shí)現(xiàn)這些需求定義。
復(fù)制粘貼代碼
隨著本教程的進(jìn)行,你很有肯能試圖從書中直接復(fù)制代碼,并粘貼到你自己的代碼編輯器中去。但是,請(qǐng)盡可能的自己手動(dòng)輸入所有的代碼。我們知道這個(gè)很無聊,但是這能幫助你更好的記住操作過程,以及那些你后面將會(huì)用到的命令。
此外,復(fù)制粘貼 Python 代碼,你很可能在自找麻煩。書中的空白區(qū)域很可能被解釋成
space,tab或者space和tab的混合體,這會(huì)導(dǎo)致大量奇奇怪怪的問題,而不一定僅僅是縮進(jìn)錯(cuò)誤。請(qǐng)?zhí)貏e留意,如果你正在使用Python 3,如果在縮進(jìn)中混合使用space和tab,將會(huì)導(dǎo)致TabError錯(cuò)誤。
現(xiàn)在絕大部分的編輯器,都能夠正確顯示空白區(qū)域是使用的
tab還是space,如果有這個(gè)功能,請(qǐng)打開它,這能幫你解決不少困惑。