Python學習之路19-設置應用程序的樣式並對其進行部署

本系列是對入門書籍《Python編程:從入門到實踐》的筆記整理,屬於初級內容。標題順序採用書中標題。

本篇將對Django項目做最後的完善。本篇也是這本書的最後一篇。

1. 前言

在本篇中,我們將:

  • 使用Bootstrap庫設置樣式;

  • 把項目部署到Heroku上。

2. 設置項目“學習筆記”的樣式

之前關注的都是項目的功能,現在來為項目添加樣式。

我們將使用django-bootstrap3來設置樣式。首先請在虛擬環境中安裝這個第三方庫。

然後像之前在項目settings.py中註冊我們自己編寫的APP一樣,註冊bootstrap3這個應用程序。

還需要包含django-bootstrap3包含jQuery,在settings.py末尾添加如下代碼:

Python學習之路19-設置應用程序的樣式並對其進行部署

2.1 修改base.html

2.1.1 定義HTML頭部

實現訪問項目的每個頁面時,瀏覽器標題都現實這個網站的名稱。另外還添加了一些在模板中使用Bootstrap所需的信息。刪除base.html的全部代碼,並添加如下代碼:

Python學習之路19-設置應用程序的樣式並對其進行部署

第12行使用了django-bootstrap3的一個自定義模板標籤,它讓Django包含所有的Bootstrap樣式文件。第13行啟用可能在頁面中使用的所有交互式行為,如可摺疊的導航欄。

2.1.2 定義導航欄

Python學習之路19-設置應用程序的樣式並對其進行部署

navbar、navbar-default和navbar-static-top是三個選擇器,在nav塊中的內容將根據選擇器在Bootstrap中定義的樣式規則來設置樣式(額,html中選擇器的概念有點忘了,不過不要緊,我們的任務並不是研究HTML)。在第20-28行中是我們之前編寫的判斷語句,只不過被放在了ul塊中,並且設置了一個選擇器navbar-right。

2.1.3 定義頁面的主要部分

Python學習之路19-設置應用程序的樣式並對其進行部署

這部分包含一個div塊,該塊的class屬性是container(容器),容器中包含兩個元素:一個新增的header塊和之前用到的content塊。header塊的內容告訴用戶頁面包含哪些信息以及用戶可以在頁面上執行哪些操作,其class屬性值page-header將一系列樣式應用於這個塊。base.html的修改到此為止。

2.2 使用jumbotron設置主頁樣式

下面使用新定義的header塊及另一個名為jumbotron的Bootstrap元素修改主頁。jumbotron元素是一個大框,通常用於在主頁中呈現項目的簡要描述,修改index.html:

Python學習之路19-設置應用程序的樣式並對其進行部署

在header塊中,我們用一個jumbotron元素來修飾一條簡短的標語,讓首次訪問者大致知道網站功能。隨後再content塊中描述了兩種主要操作。下圖是實際效果:

Python學習之路19-設置應用程序的樣式並對其進行部署

2.3 設置登錄頁面樣式

現在的代碼改進了登錄頁面的整體外觀(因為修改了base.html),現在來改進登錄表單,修改login.html:

Python學習之路19-設置應用程序的樣式並對其進行部署

第2行代碼加載了bootstrap3模板標籤;

header塊描述這個頁面時做什麼的;

刪除了之前的 if form.errors代碼塊,因為django-bootstrap3位自動管理表單錯誤;

form塊中添加了屬性“form”,然後使用標籤模板bootstrap_form來顯示錶單,這個標籤替換掉了之前的form.as_p;

button也使用Bootstrap樣式進行了替換,下面是實際效果圖:

Python學習之路19-設置應用程序的樣式並對其進行部署

2.4 設置new_topic.html頁面樣式

Python學習之路19-設置應用程序的樣式並對其進行部署

上面的修改大多都類似於對login.html的修改。

2.5 設置topics.html頁面樣式

Python學習之路19-設置應用程序的樣式並對其進行部署

這裡並沒有加載bootstrap3,因為該文件中並沒有使用任何bootstrap3自定義標籤。

2.6 設置topic.html中條目的樣式

topic頁面包含的內容比其他大部分頁面都多,所以樣式設置要多一些,我們將使用Bootstrap面板(panel)來突出每個條目。

Python學習之路19-設置應用程序的樣式並對其進行部署

只修改了樣式,並沒有修改Django代碼。下圖是實際效果:

Python學習之路19-設置應用程序的樣式並對其進行部署

至此已完成了對頁面的修改。

3. 部署“學習筆記”

由於對Web應用不是很瞭解,筆者查閱資料現在大多用Apache和Nginx來部署Web項目,但本書使用Heroku來部署我們的Web項目。

請到Heroku的官網註冊賬號,它提供免費使用服務,併到https://toolbelt.heroku.com/ 下載命令行工具。

同時,還需要在Django項目所在的虛擬環境中安裝一些額外的包:

dj-database-url:幫助Django與Heroku使用的數據庫進行通信;

dj-static,static3:幫助Django正確管理靜態文件(靜態文件包括樣式規則和JavaScript文件);

gunicorn:一個服務器軟件,能夠在在線環境中支持應用程序提供的服務。

3.1 創建包含包列表的文件requirements.txt

Heroku需要知道我們的項目依賴於哪些包,使用pip命令來生成這個文件:

Python學習之路19-設置應用程序的樣式並對其進行部署

下面是這個文件所包含的內容(“如果是windows系統,看到的內容可能不全”——這是書中提示,然而這裡的內容還比書中多了一個pytz):

Python學習之路19-設置應用程序的樣式並對其進行部署

在部署項目時,Heroku將創建一個環境,並根據這個文件安裝其中的所有包。也因此,項目部署到Heroku後,行為將與它在本地系統上一樣。

還需要在包列表中添加psycopg2,它幫助Heroku管理活動數據庫。需在requirements.txt最後一行添加如下代碼:psycopg2>=2.6.1。該語句表示,有新版則裝最新版,沒有的話最低安裝2.6.1版本。

3.2 確定Python版本

如果沒有指定Python版本,Heroku將使用其當前的Python默認版本。下面來確保Heroku使用我們所使用的版本。如果不知道使用的python的版本,請在項目所在虛擬環境中執行python –version:

Python學習之路19-設置應用程序的樣式並對其進行部署

再在manage.py所在的文件夾中新建一個名為runtime.txt的文件,輸入python的版本:

Python學習之路19-設置應用程序的樣式並對其進行部署

注意:單詞小寫,中間有一個連字符!

3.3 為部署到Heroku而修改settings.py

在settings.py末尾添加一個片段,指定一些Heroku環境設置:

Python學習之路19-設置應用程序的樣式並對其進行部署

第2行中,使用getcwd()函數獲取當前的工作目錄,在Heroku中,這個目錄總/app。在本地部署中,這個目錄通常是項目文件的名稱。這個if測試確保僅當項目被部署到Heroku時才運行這個代碼塊。

這種結構讓我們能夠將統一配置文件用於本地開發環境和在線服務器。

在第3行,導入了dj_database_url,用於在Heroku上配置服務器。Heroku使用PostgreSQL(也叫Postgres,一種比SQLite更高級的數據庫),這些配置使得項目在Heroku上使用該數據庫。

其他配置作用分別如下:支持HTTPS請求(第10行);讓Django能夠使用Heroku的URL來提供項目支持的服務(第13行);設置項目,使其能夠在Heroku上正確地提供靜態文件(第16-20行)。

3.4 創建啟動進程的Procfile

Procfile告訴Heroku啟動那些進程,以便能夠正確地提供項目支持的服務。這個文件只包含一行,文件名為Procfile,不帶擴展名,保存到項目根目錄。

Python學習之路19-設置應用程序的樣式並對其進行部署

這段代碼讓Heroku將gunicorn用過服務器,並使用learning_log/wsgi.py中的設置來啟動應用程序。標誌log-file告訴Heroku應將哪些類型的時間寫入日誌。

3.5 為部署到Heroku而修改wsgi.py

因為Heroku需要的設置與目前一直使用的設置稍有不同,所以還需要修改wsgi.py文件:

Python學習之路19-設置應用程序的樣式並對其進行部署

注意,這裡只有第4,9行是添加的,其餘都是自帶的。

3.6 創建用於存儲靜態文件的目錄

在Heroku上,Django蒐集所有的靜態文件,並將它們放在一個地方,以便高效管理。我們需要手動創建這樣一個文件夾。在項目文件夾learning_log中,也有一個名為learning_log的子文件夾,在這個子文件夾中,新建一個名為static的文件夾,即這個文件夾的路徑為:learning_log/learning_log/static/。由於項目被推送到Heroku時,它將不包含空文件夾,所以,在static文件夾中還需要創建一個佔位文件placeholder.txt:

Python學習之路19-設置應用程序的樣式並對其進行部署

3.7 在本地使用gunicorn服務器

如果你使用的是Linux或OS X,可在部署到Heroku前嘗試在本地使用gunicorn服務器。為此,在虛擬環境中執行命令:

Python學習之路19-設置應用程序的樣式並對其進行部署

但如果使用的是Windows,請跳過這個步驟(筆者用的是Windows,所以上面的輸出是從書上照搬過來的)。

3.8 使用Git跟蹤項目文件

Heroku Toolbelt包含Git,這裡不再介紹Git怎麼安裝。

Git跟蹤誰修改了項目,即便項目由一個人開發。為了實現跟蹤,需要提供用戶名和email,但對於聯繫項目,這倆都可以隨便起:

Python學習之路19-設置應用程序的樣式並對其進行部署

我們無需讓Git跟蹤項目中的每個文件,因此將讓Git忽略一些文件。在項目根目錄下創建一個名為 .gitignore 的文件,注意前面有一個實心句點,不含擴展名。在文件中輸入:

Python學習之路19-設置應用程序的樣式並對其進行部署

如果你使用的是PyCharm,還需要包括 .idea/

忽略ll_env目錄是因為隨時都可以重新創建它;忽略__pycache__是因為這個目錄包含了Django運行.py文件時自動創建的.pyc文件,目前都是本地數據(如果使用的是python2.7,請將__pycache__替換為*.pyc);沒有跟蹤本地數據庫是因為如果你在服務器上使用的是SQLite,當你將項目推送到服務器時,可能會不小心把服務器上的數據給覆蓋掉。

最後,我們提交項目,而在提交之前需要為我們的項目初始化一個Git倉庫,將所有必要的文件都加入到這個倉庫中,並提交項目的初始狀態,如下:

Python學習之路19-設置應用程序的樣式並對其進行部署

第一個命令在“學習筆記”所在的目錄中初始化一個空倉庫;第二個命令(最後有個句點!)將未被忽略的文件都添加到這個倉庫中;第三個命令中的標誌 -a 讓Git在這個提交中包含所有修改過的文件,而標誌 -m 讓Git記錄一條日誌消息;第四個命令的輸出表明當前位於分支master中,而工作目錄是乾淨(clean)的,每當要將項目推送到Heroku時,都希望看到這個狀態。

3.9 推送到Heroku

現在開始推送項目。在項目的虛擬環境中執行下面的命令:

Python學習之路19-設置應用程序的樣式並對其進行部署

首先,在終端會話中,使用你在Heroku官網創建的賬號登陸,然後讓Heroku創建一個空項目。Heroku生成的項目名由兩個單詞和一個數字組成(可以修改)。然後我們讓Git將項目分值master推送到Heroku剛才建立的倉庫中;Heroku隨後使用這些文件在其服務器上創建項目。最後輸出信息還給出了訪問這個項目的URL。

大概上述命令執行完後,項目便部署好了,但還未對其做全面的配置。為核實正確地啟動了服務器進程,請執行命令heroku ps:

Python學習之路19-設置應用程序的樣式並對其進行部署

當執行了這條命令後,輸出指出項目還可在多長時間內處於活動狀態。當超過這個時間後,將顯示標準的服務器錯誤頁面,而稍後我們將設置這個錯誤頁面。在倒數第二行,我們發現啟動了Procfile指定的進程。

現在,我們可以使用命令heroku open在瀏覽器中打開這個APP了(也可以在網頁直接打開):

Python學習之路19-設置應用程序的樣式並對其進行部署

它將自動打開瀏覽器,顯示項目的主頁。

3.10 在Heroku上建立數據庫

要對Heroku項目執行Django和Python命令,可使用命令heroku run:

Python學習之路19-設置應用程序的樣式並對其進行部署

當執行上述命令後,Heroku創建一個終端會話來執行命令migrate(第2行)。從第6行起,Django應用默認遷移以及我們在開發“學習筆記”期間生成的遷移。

現在可以像在本地系統上一樣使用它。然而其中並沒有任何數據,因為之前的測試數據並沒有複製到服務器中,而且也不建議將測試數據複製到服務器中。

3.11 改進Heroku部署

3.11.1 在Heroku上創建超級用戶

從上面的命令可以看出,我們可以使用heroku run來執行一次性命令,但可以這樣執行命令:在連接到了Heroku服務器的情況下,使用命令heroku run bash來打開Bash終端會話。我們將使用Bash終端會話來創建超級用戶,以便能夠訪問在線應用程序的管理網站:

Python學習之路19-設置應用程序的樣式並對其進行部署

進入bash後,我們首先執行了ls命令,以查看服務器上有哪些文件和目錄,發現和本地系統相同。然後我們執行了常見超級用戶的命令,執行過程和之前創建超級用戶一樣。現在可以通過在APP的URL後面加/admin/來登陸管理網站了。

3.11.2 在Heroku上創建對用戶友好的URL

由於在服務器上我們的項目名不是learning_log,而是其他自動生成的名字,為此,我們使用一個命令來重命名這個APP:

Python學習之路19-設置應用程序的樣式並對其進行部署

3.12 確保項目的安全

當前這個項目存在一個嚴重的安全問題:settings.py中包含設置DEBUG=True,它在發生錯誤時顯示調試信息。開發項目時,Django的錯誤頁面向你顯示了重要的調試信息,如果將項目部署到服務器後依然保留這個設置,講給攻擊者提供大量可供利用的信息。我們還需要確保任何人都無法看到這些信息,也不能冒充項目託管網站來重定向請求。

下面修改settings.py文件,以讓我們能夠在本地看到錯誤信息,但部署到服務器後不顯示任何錯誤信息:

Python學習之路19-設置應用程序的樣式並對其進行部署

然後我們提交併推送修改。先將修改提交到Git倉庫,在推送到Heroku:

Python學習之路19-設置應用程序的樣式並對其進行部署

Heroku發現倉庫發生了變化,因此重建了項目,確保所有的修改都已生效。它不會重建數據庫,因此本次無需執行命令migrate。

現在如果訪問未定義的擴展將會看到一個標準的錯誤頁面,它不包含任何關於項目的具體信息。

3.13 創建自定義錯誤頁面

編寫兩個風格與我們項目相符的404和500錯誤頁面模板。這些模板必須放在根模板目錄中。為此,在文件夾leraning_log/learning_log中新建一個文件夾templates,再在這個文件夾中新建一個404.html文件,並輸入如下內容:

Python學習之路19-設置應用程序的樣式並對其進行部署

再創建一個名為500.html的文件:

Python學習之路19-設置應用程序的樣式並對其進行部署

這些新文件要求對settings.py做細微的修改:

Python學習之路19-設置應用程序的樣式並對其進行部署

在將修改推送到服務器之前,可以在本地查看錯誤頁面時什麼樣的,不過得先在本地設置DEBUG=False:

Python學習之路19-設置應用程序的樣式並對其進行部署

現在本地訪問不存在的頁面時將得到我們自定義的錯誤頁面。

最後,想之前一樣,將修改推送到服務器,代碼不再演示,注意為推送添加一條簡短的日誌信息。

現在,如果用戶手工請求不存在的主題或條目將導致500錯誤。Django嘗試渲染請求的頁面,但沒有足夠的信息來完成這項任務,進而引發500錯誤。對於這種情況,將其視為404錯誤更合適,為此可使用Django快捷函數get_object_or_404()。這個函數嘗試從數據庫獲取請求的對象,當對象不存在時,引發404錯誤。我們在views.py中導入這個函數,並用它替換函數get():

Python學習之路19-設置應用程序的樣式並對其進行部署

再次提交併推送修改。

3.14 部署總結

從前面這些例子可看出,開發與部署的過程如下:

①修改項目。如果創建了新文件,使用命令 git add . (最後有個句點!)將它們加到Git倉庫中。如果要遷移數據庫,也需要執行該命令,因為每個遷移都生成了新的遷移文件。

②執行 git commit -am “commit message”,將修改提交到倉庫。

③執行 git push heroku master 將修改推送到服務器。

④如果本地遷移了數據庫,也需要遷移在線數據庫,可以使用一次性命令 heroku run python manage.py migrate ,也可以使用 heroku run bash打開一個遠程終端會話,再執行遷移。

3.15 設置SECRET_KEY

Django根據settings.py中的SECRET_KEY來實現大量的安全協議。本項目中設置的SECRET_KEY對一個練習項目來說已經足夠了,但是對於生產網站,請務必認真對待這個值。

3.16 將項目從Heroku刪除

Heroku限制了你可免費託管的項目數,另外,我們也不希望自己的賬戶中塞滿大量的聯繫項目。除了可以登錄到Heroku,在應用程序的Settings中手動刪除項目,也可以在命令行中執行如下命令刪除項目:

Python學習之路19-設置應用程序的樣式並對其進行部署

4. 總結

現在大家網址 https://kevins-learning-log.herokuapp.com 訪問這個網站(筆者在免費期過期前不會刪除這個網站)。本篇主要介紹瞭如何使用Bootstrap來設置網頁的樣式,並學習瞭如何將項目部署到Heroku的服務器上。至此,Python的Django入門已經完成,這本書也已經看完。暫時告一段落。

還有件事需要向大家通知一下,可能以後不會像現在這樣頻繁地更新文章了。寫文章是個很費時間的活,筆者看這本書,如果不寫博客的話,這本書一個周就看完了,但不記筆記又容易忘,可現在筆者更新的這些文章根本不叫筆記,應該叫做抄書,這並不是我的初衷。所以,以後的文章會更偏向於總結性質。望請見諒~~~


分享到:


相關文章: