6. django 博客首頁視圖

本教程內(nèi)容已過時勃黍,更新版教程請訪問: Django 博客開發(fā)入門教程拼岳。

這是 Django 博客教程的第 6 篇优妙,在閱讀此篇教程以前助琐,請確保你已閱讀 Django 博客教程的前 5 篇:
1. Django 博客教程:前言
2. 搭建開發(fā)環(huán)境
3. 建立我們的 django 博客應(yīng)用
4. 創(chuàng)建 django 博客的數(shù)據(jù)庫模型
5. 讓 django 完成翻譯——遷移數(shù)據(jù)庫模型

django 是如何處理 http 請求的

Web 應(yīng)用的交互過程其實就是 http 請求與響應(yīng)的過程烙丛。無論是在 PC 端還是移動端舅巷,我們通常使用瀏覽器來上網(wǎng),我們的上網(wǎng)流程大致來說是這樣的:

  1. 我們打開瀏覽器河咽,在地址欄輸入我們想訪問的網(wǎng)址钠右,比如 www.djangoproject.com(當(dāng)然你也可能從收藏夾里直接打開網(wǎng)站,但本質(zhì)上都是一樣的忘蟹。)
  2. 瀏覽器知道我們想要訪問那個網(wǎng)址后飒房,它在后臺幫我們做了很多事情,主要就是把我們的訪問意圖包裝成一個 http 請求媚值,發(fā)給我們想要訪問的網(wǎng)址所對應(yīng)的服務(wù)器狠毯。通俗點說就是瀏覽器幫我們通知網(wǎng)站的服務(wù)器,說有人來訪問你啦褥芒,訪問的請求都寫在 http 里了垃你,你按照要求處理后告訴我,我再幫你回應(yīng)他喂很!
  3. 網(wǎng)站服務(wù)器處理了 http 請求惜颇,然后生成一段 http 響應(yīng)給瀏覽器,瀏覽器解讀這個響應(yīng)少辣,把相關(guān)的內(nèi)容在瀏覽器里顯示出來凌摄,于是我們就看到了網(wǎng)站的內(nèi)容。比如你訪問了社區(qū)主頁 www.pythonzh.cn漓帅,服務(wù)器接收到這個請求后他就知道用戶訪問的是首頁锨亏,首頁顯示的是全部帖子列表痴怨,于是它從數(shù)據(jù)庫里把帖子數(shù)據(jù)取出來,生成一個寫著這些數(shù)據(jù)的 html 文檔器予,包裝到 http 響應(yīng)里發(fā)給瀏覽器浪藻,瀏覽器解讀這個響應(yīng),把 html 文檔顯示出來乾翔,我們就看到了帖子列表的內(nèi)容爱葵。

因此,django 作為一個 web 框架反浓,它的使命就是處理流程中的第二步萌丈,接收瀏覽器發(fā)來的 http 請求,返回相應(yīng)的 http 響應(yīng)雷则。于是引出這么幾個問題:

  1. django 如何接收 http 請求辆雾?
  2. django 如何處理這個 http 請求?
  3. django 如何生成 http 響應(yīng)月劈?

對于如何處理這些問題度迂,django 有其自身的一套規(guī)定的機(jī)制。我們按照 django 的規(guī)定猜揪,就能開發(fā)出我們所需的功能惭墓。我們先以一個最簡單的 hello world 為例來看看 django 處理上述問題的機(jī)制是怎么樣的。

首先 django 需要知道當(dāng)用戶訪問不同的網(wǎng)址時湿右,應(yīng)該如何處理不同的網(wǎng)址。django 的做法是把不同的網(wǎng)址對應(yīng)的處理函數(shù)寫在一個 urls.py 文件里罚勾,當(dāng)用戶訪問某個網(wǎng)址時毅人,django 就去會這個文件里找,如果找到這個網(wǎng)址尖殃,就會調(diào)用和它綁定在一起的處理函數(shù)(叫做視圖函數(shù))丈莺,下面是具體的做法,首先在 blog 應(yīng)用的目錄下創(chuàng)建一個 urls.py 文件送丰,這時你的目錄看起來是這樣:

blog/
    __init__.py
    admin.py
    apps.py
    migrations/
        0001_initial.py
        __init__.py
    models.py
    tests.py
    views.py
    urls.py # 新建的文件

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

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
]

我們首先從 django.conf.urls 導(dǎo)入了 url 函數(shù)缔俄,又從當(dāng)前目錄下導(dǎo)入了 views 模塊。然后我們把網(wǎng)址和處理函數(shù)的關(guān)系寫在了 urlpatterns 列表里器躏。綁定關(guān)系的寫法是把網(wǎng)址和對應(yīng)的處理函數(shù)作為參數(shù)傳給 url 函數(shù)(第一個參數(shù)是網(wǎng)址俐载,第二個參數(shù)是處理函數(shù)),另外我們還傳遞了另外一個參數(shù) name登失,這個參數(shù)的值將作為處理函數(shù) index 的別名遏佣,這在以后會用到。

注意這里我們的網(wǎng)址是用正則表達(dá)式寫的揽浙,django 會用這個正則表達(dá)式去匹配用戶實際輸入的網(wǎng)址状婶,如果匹配成功意敛,就會調(diào)用其后面的視圖函數(shù)做相應(yīng)的處理。比如說我們本地開發(fā)服務(wù)器的域名是 127.0.0.1:8000膛虫,那么當(dāng)用戶輸入網(wǎng)址:127.0.0.1:8000 后草姻,django 首先會把域名(即 127.0.0.1)和端口號(8000)去掉,此時只剩下一個空字符串稍刀,而 r'^$' 的模式正是匹配一個空字符串(這個正則表達(dá)式的意思是以空字符串開頭且以空字符串結(jié)尾)撩独,于是二者匹配,django 便會調(diào)用其對應(yīng)的 views.index 函數(shù)掉丽。

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

blog/views.py

from django.http import HttpResponse

def index(request):
    return HttpResponse("歡迎訪問我的博客首頁!")

我們前面說過捶障,Web 服務(wù)器的作用就是接收來自用戶的 http 請求僧须,根據(jù)請求內(nèi)容作出相應(yīng)的處理,并把處理結(jié)果包裝成 http 響應(yīng)返回給用戶项炼。這個兩行的函數(shù)體現(xiàn)了這個過程担平。它首先接受了一個名為 request 的參數(shù),這個 request 就是 django 為我們封裝好的 http 請求锭部,它是類 HttpResponse 的一個實例暂论。然后我們便直接返回了一個 http 響應(yīng)給用戶,這個 http 響應(yīng)也是 django 幫我們封裝好的拌禾,它是類 HttpResponse 的一個實例取胎,只是我們給它傳了一個自定義的字符串,用戶接受到這個響應(yīng)后就會在瀏覽器顯示出我們傳遞的內(nèi)容:“歡迎訪問我的博客首頁湃窍!”

還差最后一步了闻蛀,我們前面建立了一個 urls.py 文件,并且綁定了 URL 和視圖函數(shù) index您市,但是 django 并不知道觉痛。django 匹配 url 是在 blogproject 的 urls.py 下的,所以我們要把我們自己寫的 urls.py 文件包含到這個文件里去茵休,打開這個文件看到如下內(nèi)容:

"""
一大段注釋
"""

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

修改成如下的形式:

- from django.conf.urls import url
+ from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
+   url(r'', include('blog.urls')),
]

這里 - 表示刪掉這一行薪棒,+ 表示添加這一行。我們這里導(dǎo)入了一個 include 函數(shù)榕莺,然后利用這個函數(shù)把 blog 應(yīng)用下的 urls.py 包含了進(jìn)來俐芯。此外 include 前還有一個 r'',這是一個空字符串钉鸯,這里也可以寫其他字符串泼各,django 會把這個字符串和后面 include 的 urls.py 文件中的 url 拼接。假如我們這里把 r'' 改成 r'blog/'亏拉,而我們在 blog.urls 中寫的url 是 r'^$'扣蜻,一個空字符串逆巍,那么 django 最終匹配的就是 blog/ 加上一個空字符串,即 blog/莽使。

運行 python manage.py runserver 打開開發(fā)服務(wù)器锐极,在瀏覽器輸入開發(fā)服務(wù)器的地址 http://127.0.0.1:8000/,可以看到我們返回的內(nèi)容了:歡迎訪問我的博客首頁芳肌!

這基本上就上 django 的開發(fā)流程了灵再,寫好處理 http 請求和返回 http 響應(yīng)的視圖函數(shù),然后把視圖函數(shù)綁定到相應(yīng)的 URL 上亿笤。但是等一等翎迁!我們看到在我們的視圖函數(shù)里返回的是一個 HttpResponse 類的實例,我們給他傳入了一個我們希望顯示在用戶瀏覽器上的字符串净薛。但是我們的博客不可能只顯示這么一句話汪榔,它有可能會顯示很長很長的內(nèi)容,比如我們發(fā)布的博客文章列表肃拜,或者一大段的博客文章痴腌,我們不能每次都把這些大段大段的內(nèi)容傳給 HttpResponse 。于是 django 對這個問題給我們提供了一個好的方法燃领,叫做模板系統(tǒng)士聪。django 要我們把大段的文本寫到一個文件里,然后 django 自己會去讀取這個文件猛蔽,django 再把讀取到的內(nèi)容傳給 HttpResponse剥悟。我們用模板系統(tǒng)來改造一下上面的例子。首先在我們的項目根目錄下建立一個名為 templates 的文件夾曼库,用來存放我們的模板区岗。然后再建立一個名為 blog 的文件夾,用來存放和 blog 應(yīng)用相關(guān)的模板凉泄。當(dāng)然模板存放在哪里是無關(guān)緊要的躏尉,只要 django 能夠找到的就好蚯根。但是我們建立這樣的文件夾結(jié)構(gòu)的目的是把不同應(yīng)用用到的模板隔離開來后众,這樣方便以后維護(hù),養(yǎng)成良好的習(xí)慣颅拦。然后我們在 blog 目錄下建立一個名為 index.html 的文件蒂誉,寫上下面的代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
<h1>{{ welcome }}</h1>
</body>
</html>

這是一個標(biāo)準(zhǔn)的 html 文檔了,只是里面有兩個比較奇怪的地方:{{ title }}距帅,{{ welcome }}右锨,這是 django 規(guī)定的語法。用 {{ }} 包起來的叫做模板變量碌秸。django 在讀取這個模板的時候回根據(jù)我們傳來值替換這些變量绍移。最終在模板中顯示的將會是我們傳遞的值悄窃。

模板寫好了,還得告訴 django 去哪里找模板蹂窖,在 settings.py 文件里設(shè)置一下模板文件所在的路徑轧抗。在 settings.py 找到 TEMPLATES 選項,它的內(nèi)容是這樣的:

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',
            ],
        },
    },
]

其中 DIRS 就是設(shè)置模板的路徑瞬测,在 [] 中寫入 os.path.join(BASE_DIR, 'templates')横媚,變成這樣:

blogproject/settings.py

TEMPLATES = [
    {
        ...
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        ...
    },
]

這里 BASE_DIR 是 settings.py 前面定義的變量,記錄的是工程根目錄 blogproject 的值月趟,在這個目錄下有我們的模板目錄 templates灯蝴,于是利用os.path.join 把這兩個路徑連起來,構(gòu)成完整的模板路徑孝宗,django 就知道去這個路徑下面找我們的模板了穷躁。

視圖函數(shù)可以改一下了:

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': '歡迎訪問我的博客首頁'
                  })

這里我們在是直接把字符串傳給 HttpResponse 了,而是調(diào)用 django 提供了 render 函數(shù)碳褒,這個函數(shù)根據(jù)我們傳入的參數(shù)來構(gòu)造 HttpResponse折砸。我們首先把 http 請求傳了進(jìn)去,然后它根據(jù)第二個參數(shù)的值 blog/index.html 找到我們的模板沙峻,然后讀取模板中的內(nèi)容睦授,并且根據(jù)我們傳入的 context 把模板中的變量替換為我們傳遞的值,{{ title }} 被替換成了 context 字典中 title 對應(yīng)的值摔寨,同理 {{ welcome }} 也被替換成相應(yīng)的值去枷。最終,我們的 html 模板中的內(nèi)容字符串被傳遞給 HttpResponse 對象并返回給瀏覽器是复,這樣用戶的瀏覽器上便顯示出了我們寫的 html 模板的內(nèi)容删顶。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市淑廊,隨后出現(xiàn)的幾起案子逗余,更是在濱河造成了極大的恐慌,老刑警劉巖季惩,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件录粱,死亡現(xiàn)場離奇詭異,居然都是意外死亡画拾,警方通過查閱死者的電腦和手機(jī)啥繁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來青抛,“玉大人旗闽,你說我怎么就攤上這事。” “怎么了适室?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵嫡意,是天一觀的道長。 經(jīng)常有香客問我捣辆,道長鹅很,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任罪帖,我火速辦了婚禮促煮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘整袁。我一直安慰自己菠齿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布坐昙。 她就那樣靜靜地躺著绳匀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪炸客。 梳的紋絲不亂的頭發(fā)上疾棵,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音痹仙,去河邊找鬼是尔。 笑死,一個胖子當(dāng)著我的面吹牛开仰,可吹牛的內(nèi)容都是我干的拟枚。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼众弓,長吁一口氣:“原來是場噩夢啊……” “哼恩溅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谓娃,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤脚乡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后滨达,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奶稠,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年弦悉,在試婚紗的時候發(fā)現(xiàn)自己被綠了窒典。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蟆炊。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡稽莉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涩搓,到底是詐尸還是另有隱情污秆,我是刑警寧澤劈猪,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站良拼,受9級特大地震影響战得,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜庸推,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一常侦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贬媒,春花似錦聋亡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至脖含,卻和暖如春罪塔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背养葵。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工征堪, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人关拒。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓请契,卻偏偏與公主長得像,于是被迫代替她去往敵國和親夏醉。 傳聞我的和親對象是個殘疾皇子爽锥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容