當前位置:
首頁 > 最新 > 手把手教你用Django搭建博客(三)

手把手教你用Django搭建博客(三)

作者:楊學光

博客:http://zmrenwu.com/

往期回顧:

手把手教你用Django搭建博客(一)

手把手教你用Django搭建博客(二)

5、讓 Django 完成翻譯:遷移資料庫

我們已經編寫了博客資料庫模型的代碼,但那還只是 Python 代碼而已,Django 還沒有把它翻譯成資料庫語言,因此實際上這些資料庫表還沒有真正的在資料庫中創建。

遷移資料庫

為了讓 Django 完成翻譯,創建好這些資料庫表,我們再一次請出我的工程管理助手 manage.py。激活虛擬環境,切換到 manage.py 文件所在的目錄下,分別運行和命令:

注意:如果代碼中含有中文注釋,且你使用的是 Python 2 開發環境的話,會得到一個編碼錯誤。因此請在含有中文注釋的文件最開始處加入編碼聲明:# coding: utf-8。

當我們執行了後,Django 在 blog 應用的 migrations 目錄下生成了一個 0001_initial.py 文件,這個文件是 Django 用來記錄我們對模型做了哪些修改的文件。目前來說,我們在 models.py 文件里創建了 3 個模型類,Django 把這些變化記錄在了 0001_initial.py 里。

不過此時還只是告訴了 Django 我們做了哪些改變,為了讓 Django 真正地為我們創建資料庫表,接下來又執行了命令。Django 通過檢測應用中 migrations 目錄下的文件,得知我們對資料庫做了哪些操作,然後它把這些操作翻譯成資料庫操作語言,從而把這些操作作用於真正的資料庫。

你可以看到命令的輸出除了 Applying blog.0001_initial... OK 外,Django 還對其它文件做了操作。這是因為除了我們自己建立的 blog 應用外,Django 自身還內置了很多應用,這些應用本身也是需要存儲數據的。可以在 settings.py 的設置里看到這些應用,當然我們目前不必關心這些。

對於了解資料庫語言的人,你可以運行下面的命令看看 Django 究竟為我們做了什麼:

你將看到輸出了經 Django 翻譯後的資料庫表創建語句,這有助於你理解 Django ORM 的工作機制。

選擇資料庫版本

我們沒有安裝任何的資料庫軟體,Django 就幫我們遷移了資料庫。這是因為我們使用了 Python 內置的 SQLite3 資料庫。

SQLite3 是一個十分輕巧的資料庫,它僅有一個文件。你可以看一到項目根目錄下多出了一個 db.sqlite3 的文件,這就是 SQLite3 資料庫文件,Django 博客的數據都會保存在這個資料庫文件里。

Django 在 settings.py 里為我們做了一些默認的資料庫配置:

可以看到默認的資料庫引擎就是使用的 SQLite3。

當然一些人傾向於使用 MySQL 等大型資料庫,至於 Django 如何配置 MySQL 這裡就不贅述了,你可以自行使用搜索引擎或者查閱 Django 的官方文檔解決。對於一個小型博客而言,SQLite3 資料庫足以勝任。

用 Django 的方式操作資料庫

資料庫最主要的操作就是往裡面存入數據、從中取出數據、修改已保存的數據和刪除不再需要的數據。和創建資料庫表一樣,Django 為這些操作提供了一整套方法,從而把我們從資料庫語言中解放出來。我們不用學習如何利用資料庫語言去完成這些操作,只要簡單地調用幾個 Python 函數就可以滿足我們的需求。

存數據

先在命令行中來探索一下這些函數,感受一下如何用 Django 的方式來操作資料庫。在 manage.py 所在目錄下運行命令:

這打開了一個互動式命令行。

首先我們來創建一個分類和一個標籤:

我們首先導入 3 個之前寫好的模型類,然後實例化了一個類和一個類,為他們的屬性賦了值。為了讓 Django 把這些數據保存進資料庫,調用實例的方法即可。

再創建一篇文章試試,但創建文章之前,我們需要先創建一個 User,用於指定文章的作者。創建 User 的命令 Django 已經幫我們寫好了,依然是通過 manage.py 來運行。首先按住 Ctrl + c 退出命令交互欄(一次退不出就連續多按幾次),運行命令並根據提示創建用戶:

運行開始創建用戶,之後會提示你輸入用戶名、郵箱、密碼和確認密碼,按照提示輸入即可。注意一點的是密碼輸入過程中不會有任何字元顯示,不要誤以為你的鍵盤出問題了,正常輸入即可。最後出現 Superuser created successfully. 說明用戶創建成功了。

再次運行進入 Python 命令交互欄,開始創建文章:

由於我們重啟了 shell,因此需要重新導入了、、以及。我們還導入了一個 Django 提供的輔助模塊 timezone,這是因為我們需要調用它的方法為和指定時間,容易理解方法返回當前時間。然後我們根據用戶名和分類名,通過方法取出了存在資料庫中的和(取數據的方法將在下面介紹)。接著我們為文章指定了、、、值,並把它和前面創建的 Category 以及 User 關聯了起來。允許為空、我們就沒有為它們指定值了。

注意:我們這裡使用方法根據 的 屬性的值獲取分類的一條記錄。 的含義是從資料庫中取出 的值為 category test 的分類記錄。確保資料庫中只有一條值為 category test 的記錄,否則 方法將返回一個 異常。如果你不小心已經存了多條記錄,請刪掉多餘的記錄。如何刪除數據請看下文。

取數據

數據已經存入資料庫了,現在要把它們取出來看看:

是我們的模型管理器,它為我們提供一系列從資料庫中取數據方法,這裡我們使用了方法,表示我們要把對應的數據全部取出來。可以看到方法都返回了數據,這些數據應該是我們之前存進去的,但是顯示的字元串有點奇怪,無法看出究竟是不是我們之前存入的數據。為了讓顯示出來的數據更加人性化一點,我們為 3 個模型分別增加一個方法:

定義好方法後,解釋器顯示的內容將會是方法返回的內容。這裡返回分類名,返回標籤名,而返回它的。

裝飾器用於兼容 Python2。如果你使用的 Python3 開發環境,去掉這個裝飾器不會有任何影響。如果你使用的 Python2 開發環境,而又不想使用這個裝飾器,則將方法改為方法即可。

先按 Ctrl + c 退出 Shell,再重新運行進入 Shell。

可以看到返回的是我們之前存入的數據。

此外我們在創建文章時提到了通過方法來獲取數據,這裡方法和方法的區別是:方法返回全部數據,是一個類似於列表的數據結構(QuerySet);而返回一條記錄數據,如有多條記錄或者沒有記錄,方法均會拋出相應異常。

改數據

嘗試修改數據:

首先通過方法根據分類名獲取值為 category test 到分類,修改它的屬性為新的值 category test new,然後調用方法把修改保存到資料庫,之後可以看到資料庫返回的數據已經是修改後的值了。、的修改也一樣。

刪數據

刪除掉數據:

先根據標題的值從資料庫中取出,保存在變數中,然後調用它的方法,最後看到返回了一個空的 QuerySet(類似於一個列表),表明資料庫中已經沒有 Post,Post 已經被刪除了。

這就是 Django 對資料庫增、刪、改、查的操作。除了上述演示的方法外,Django 還為我們提供了大量其它的方法,這些方法有一部分會在教程中使用,用到時我會講解它們的用法。但以後你開發自己的項目時,你就需要通過閱讀 Django 的官方文檔(https://docs.djangoproject.com/en/1.10/ref/models/querysets/) 來了解有哪些方法可用以及如何使用它們。

總結

本章節的代碼位於:Step4: make migrations and migrate(https://github.com/zmrenwu/django-blog-tutorial/tree/Step4_make-migrations-and-migrate)

如果遇到問題,請通過下面的方式尋求幫助。

在 讓 Django 完成翻譯:遷移資料庫 - 追夢人物的博客(http://zmrenwu.com/post/6/) 的評論區留言。

將問題的詳細描述通過郵件發送到 djangostudyteam@163.com,一般會在 24 小時內回復。

6、Django 博客首頁視圖

Django 處理 HTTP 請求

Web 應用的交互過程其實就是 HTTP 請求與響應的過程。無論是在 PC 端還是移動端,我們通常使用瀏覽器來上網,上網流程大致來說是這樣的:

我們打開瀏覽器,在地址欄輸入想訪問的網址,比如 http://zmrenwu.com/(當然你也可能從收藏夾里直接打開網站,但本質上都是一樣的)。

瀏覽器知道我們想要訪問哪個網址後,它在後台幫我們做了很多事情。主要就是把我們的訪問意圖包裝成一個 HTTP 請求,發給我們想要訪問的網址所對應的伺服器。通俗點說就是瀏覽器幫我們通知網站的伺服器,說有人來訪問你啦,訪問的請求都寫在 HTTP 里了,你按照要求處理後告訴我,我再幫你回應他!

伺服器處理了HTTP 請求,然後生成一段 HTTP 響應給瀏覽器。瀏覽器解讀這個響應,把相關的內容在瀏覽器里顯示出來,於是我們就看到了網站的內容。比如你訪問了我的博客主頁 http://zmrenwu.com/,伺服器接收到這個請求後就知道用戶訪問的是首頁,首頁顯示的是全部文章列表,於是它從資料庫里把文章數據取出來,生成一個寫著這些數據的 HTML 文檔,包裝到 HTTP 響應里發給瀏覽器,瀏覽器解讀這個響應,把 HTML 文檔顯示出來,我們就看到了文章列表的內容。

因此,Django 作為一個 Web 框架,它的使命就是處理流程中的第二步。即接收瀏覽器發來的 HTTP 請求,返回相應的 HTTP 響應。於是引出這麼幾個問題:

Django 如何接收 HTTP 請求?

Django 如何處理這個 HTTP 請求?

Django 如何生成 HTTP 響應?

對於如何處理這些問題,Django 有其一套規定的機制。我們按照 Django 的規定,就能開發出所需的功能。

Hello 視圖函數

我們先以一個最簡單的 Hello World 為例來看看 Django 處理上述問題的機制是怎麼樣的。

綁定 URL 與視圖函數

首先 Django 需要知道當用戶訪問不同的網址時,應該如何處理這些不同的網址(即所說的路由)。Django 的做法是把不同的網址對應的處理函數寫在一個 urls.py 文件里,當用戶訪問某個網址時,Django 就去會這個文件里找,如果找到這個網址,就會調用和它綁定在一起的處理函數(叫做視圖函數)。

下面是具體的做法,首先在 blog 應用的目錄下創建一個 urls.py 文件,這時你的目錄看起來是這樣:

在 blogurls.py 中寫入這些代碼:

我們首先從 django.conf.urls 導入了函數,又從當前目錄下導入了 views 模塊。然後我們把網址和處理函數的關係寫在了列表裡。

綁定關係的寫法是把網址和對應的處理函數作為參數傳給函數(第一個參數是網址,第二個參數是處理函數),另外我們還傳遞了另外一個參數,這個參數的值將作為處理函數的別名,這在以後會用到。

注意這裡我們的網址是用正則表達式寫的,Django 會用這個正則表達式去匹配用戶實際輸入的網址,如果匹配成功,就會調用其後面的視圖函數做相應的處理。

比如說我們本地開發伺服器的域名是 http://127.0.0.1:8000,那麼當用戶輸入網址 http://127.0.0.1:8000 後,Django 首先會把協議 http、域名 127.0.0.1 和埠號 8000 去掉,此時只剩下一個空字元串,而的模式正是匹配一個空字元串(這個正則表達式的意思是以空字元串開頭且以空字元串結尾),於是二者匹配,Django 便會調用其對應的函數。

注意:在項目根目錄的 blogproject 目錄下(即 settings.py 所在的目錄),原本就有一個 urls.py 文件,這是整個工程項目的 URL 配置文件。而我們這裡新建了一個 urls.py 文件,且位於 blog 應用下。這個文件將用於 blog 應用相關的 URL 配置。不要把兩個文件搞混了。

編寫視圖函數

第二步就是要實際編寫我們的視圖函數了,按照慣例視圖函數定義在 views.py 文件里:

我們前面說過,Web 伺服器的作用就是接收來自用戶的 HTTP 請求,根據請求內容作出相應的處理,並把處理結果包裝成 HTTP 響應返回給用戶。

這個兩行的函數體現了這個過程。它首先接受了一個名為的參數,這個就是 Django 為我們封裝好的 HTTP 請求,它是類的一個實例。然後我們便直接返回了一個 HTTP 響應給用戶,這個 HTTP 響應也是 Django 幫我們封裝好的,它是類的一個實例,只是我們給它傳了一個自定義的字元串參數。

瀏覽器接收到這個響應後就會在頁面上顯示出我們傳遞的內容 :歡迎訪問我的博客首頁!

配置項目 URL

還差最後一步了,我們前面建立了一個 urls.py 文件,並且綁定了 URL 和視圖函數,但是 Django 並不知道。Django 匹配 URL 模式是在 blogproject 目錄(即 settings.py 文件所在的目錄)的 urls.py 下的,所以我們要把 blog 應用下的 urls.py 文件包含到 blogprojecturls.py 里去,打開這個文件看到如下內容:

修改成如下的形式:

這裡 - 表示刪掉這一行,+ 表示添加這一行。

我們這裡導入了一個函數,然後利用這個函數把 blog 應用下的 urls.py 文件包含了進來。此外 include 前還有一個,這是一個空字元串。這裡也可以寫其它字元串,Django 會把這個字元串和後面 include 的 urls.py 文件中的 URL 拼接。比如說如果我們這裡把改成,而我們在 blog.urls 中寫的 URL 是,即一個空字元串。那麼 Django 最終匹配的就是 blog/ 加上一個空字元串,即 blog/。

運行結果

激活虛擬環境,運行打開開發伺服器,在瀏覽器輸入開發伺服器的地址 http://127.0.0.1:8000/,可以看到 Django 返回的內容了。

歡迎訪問我的博客首頁!

使用 Django 模板系統

這基本上就上 Django 的開發流程了,寫好處理 HTTP 請求和返回 HTTP 響應的視圖函數,然後把視圖函數綁定到相應的 URL 上。

但是等一等!我們看到在視圖函數里返回的是一個類的實例,我們給它傳入了一個希望顯示在用戶瀏覽器上的字元串。但是我們的博客不可能只顯示這麼一句話,它有可能會顯示很長很長的內容。比如我們發布的博客文章列表,或者一大段的博客文章。我們不能每次都把這些大段大段的內容傳給。

Django 對這個問題給我們提供了一個很好的解決方案,叫做模板系統。Django 要我們把大段的文本寫到一個文件里,然後 Django 自己會去讀取這個文件,再把讀取到的內容傳給。讓我們用模板系統來改造一下上面的例子。

首先在我們的項目根目錄(即 manage.py 文件所在目錄)下建立一個名為 templates 的文件夾,用來存放我們的模板。然後在 templates 目錄下建立一個名為 blog 的文件夾,用來存放和 blog 應用相關的模板。

當然模板存放在哪裡是無關緊要的,只要 Django 能夠找到的就好。但是我們建立這樣的文件夾結構的目的是把不同應用用到的模板隔離開來,這樣方便以後維護。我們在 templateslog 目錄下建立一個名為 index.html 的文件,

此時你的目錄結構應該是這樣的:

再一次強調 templates 目錄位於項目根目錄,而 index.html 位於 templateslog 目錄下,而不是 blog 應用下,如果弄錯了你可能會得到一個TemplateDoesNotExist 異常。如果遇到這個異常,請回來檢查一下模板目錄結構是否正確。

在 templateslogindex.html 文件里寫入下面的代碼:

html

{{ title }}

{{ welcome }}

這是一個標準的 HTML 文檔,只是裡面有兩個比較奇怪的地方:,。這是 Django 規定的語法。用 {{ }} 包起來的變數叫做模板變數。Django 在渲染這個模板的時候會根據我們傳遞給模板的變數替換掉這些變數。最終在模板中顯示的將會是我們傳遞的值。

注意:index.html 必須以 UTF-8 的編碼格式保存,且小心不要往裡面添加一些特殊字元,否則極有可能得到一個 UnicodeDecodeError 這樣的錯誤。

模板寫好了,還得告訴 Django 去哪裡找模板,在 settings.py 文件里設置一下模板文件所在的路徑。在 settings.py 找到選項,

它的內容是這樣的:

python

blogproject/settings.py

TEMPLATES = [

{

BACKEND : django.template.backends.django.DjangoTemplates ,

DIRS : [],

APP_DIRS : True,

OPTIONS : {

context_processors : [

django.template.context_processors.debug ,

django.template.context_processors.request ,

django.contrib.auth.context_processors.auth ,

django.contrib.messages.context_processors.messages ,

],

},

},

]

其中就是設置模板的路徑,在 [] 中寫入,即像下面這樣:

python

blogproject/settings.py

TEMPLATES = [

{

...

DIRS : [os.path.join(BASE_DIR, templates )],

...

},

]

這裡是 settings.py 在配置開頭前面定義的變數,記錄的是工程根目錄 blogproject 的值(注意是最外層的 blogproject 目錄)。在這個目錄下有模板文件所在的目錄 templates,於是利用把這兩個路徑連起來,構成完整的模板路徑,Django 就知道去這個路徑下面找我們的模板了。

視圖函數可以改一下了:

python

blog/views.py

from django.http import HttpResponse

from django.shortcuts import render

def index(request):

return render(request, blog/index.html , context={

title : 我的博客首頁",

welcome : 歡迎訪問我的博客首頁"

})

這裡我們不再是直接把字元串傳給了,而是調用 Django 提供的函數。這個函數根據我們傳入的參數來構造。

我們首先把 HTTP 請求傳了進去,然後根據第二個參數的值 blog/index.html 找到這個模板文件並讀取模板中的內容。之後根據我們傳入的參數的值把模板中的變數替換為我們傳遞的變數的值,被替換成了字典中對應的值,同理也被替換成相應的值。

最終,我們的 HTML 模板中的內容字元串被傳遞給對象並返回給瀏覽器(Django 在函數里隱式地幫我們完成了這個過程),這樣用戶的瀏覽器上便顯示出了我們寫的 HTML 模板的內容。

總結

本章節的代碼位於:Step5: blog index view(https://github.com/zmrenwu/django-blog-tutorial/tree/Step5_blog-index-view)

如果遇到問題,請通過下面的方式尋求幫助。

在 Django 博客首頁視圖 - 追夢人物的博客(http://zmrenwu.com/post/7/) 的評論區留言。

將問題的詳細描述通過郵件發送到 djangostudyteam@163.com,一般會在 24 小時內回復。

微信回復關鍵字即可學習

回復RR語言入門免費視頻

回復PythonPython網路爬蟲實戰

回復Spark征服Spark第一季

回復Hadoop大數據系列免費視頻

回復Excel用Excel對話數據

回復SPSS數據挖掘的SPSS之路

回復TableauTableau 精品入門視頻

回復PowerBI快速玩轉微軟Power BI

回復大數據大數據系列免費視頻

回複數據分析報告數據分析報告製作

回複數據分析數據分析師成長之路

回複數據挖掘數據挖掘原理與應用

回復機器學習R&Python機器學習

「閱讀原文」就是Django搭建的網站啦

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 天善智能 的精彩文章:

TAG:天善智能 |

您可能感興趣

手把手教你用Kaggle開啟機器學習之旅
手把手教你用Python庫Keras做預測
手把手教你用Cloud AutoML做毒蜘蛛分類器
手把手教你用Python創建簡單的神經網路
手把手教你用Python進行Web抓取
啥是佩琪?手把手教你用SolidWorks繪製小豬佩奇
手把手教你用Python進行回歸
教你用 Python和Keras 建立自己的 AlphaZero
教你用 Python和Keras 建立自己的 AlphaZero
手把手教你用Keras進行多標籤分類
教你用SolidWorks繪製小豬佩奇
美國孩子的資源國內孩子照樣用!手把手教你用Raz kids在線閱讀網
Meta2教你用雙手「把玩」超跑
米家APP支持Siri:手把手教你用Siri控制米家智能設備
擁有自己第一個區塊鏈——手把手教你用python搭建
手把手教你用Python實現「坦克大戰」,(附詳細代碼!)
教你用Python解析HTML
教你用Keras和CNN建立模型識別神奇寶貝!
時尚博主Annabelle Fleur,教你用唯美浪漫的連衣裙,詮釋別樣風情
教你用iPhone備忘錄畫菠蘿