視圖是Django應(yīng)用程序中Web頁面的“類型”痢缎,它通常提供特定的功能赠群,并且有一個(gè)特定的模板坝橡。例如哑芹,在博客應(yīng)用程序中葱弟,您可能有以下視圖:
博客主頁——顯示最新的幾個(gè)條目震蒋。
進(jìn)入“細(xì)節(jié)”頁面——一個(gè)條目的permalink頁面牵咙。
基于年的歸檔頁面——在給定的年份顯示所有月份的條目玉锌。
基于月的歸檔頁面——在給定的月份中顯示所有的日期。
基于日的歸檔頁面——顯示給定日期的所有條目瓮顽。
注釋操作——處理將評論發(fā)送到給定條目县好。
在我們的 poll 應(yīng)用程序中,我們將有以下四個(gè)視圖:
Question?“索引”頁面——顯示最新的幾個(gè)問題暖混。
Question?“細(xì)節(jié)”頁面——顯示一個(gè)問題文本缕贡,沒有結(jié)果,只有一個(gè)表單可以投票拣播。
Question?“結(jié)果”頁面——顯示一個(gè)特定問題的結(jié)果晾咪。
Vote action——在一個(gè)特定的問題上處理投票給特定的選擇。
在Django中贮配,web頁面和其他內(nèi)容由視圖交付谍倦。每個(gè)視圖都由一個(gè)簡單的Python函數(shù)(或方法,在基于類的視圖的情況下)表示泪勒。Django將通過檢查所請求的URL(確切地說昼蛀,是域名后面的URL的一部分)來選擇一個(gè)視圖。
寫多個(gè)視圖
1. 編輯:?polls/views.py
2. 把這些新視圖連接到 polls.urls 模塊,通過添加以下path()調(diào)用
看一下你的瀏覽器圆存,在“/poll/34/”叼旋。它會運(yùn)行detail()方法,并顯示您在URL中提供的任何ID沦辙。試試“/poll/34/results/”和“/poll/34/vote/”——這些將顯示占位符結(jié)果和投票頁面夫植。
當(dāng)有人從你的網(wǎng)站上請求一個(gè)頁面——比如“/polls/34/”,Django會加載mysite.urls? Python模塊油讯,因?yàn)樗怯?ROOT_URLCONF (ROOT_URLCONF ='dgtest.urls') 設(shè)置指向的详民。它找到了名為urlpatterns的變量,并按順序遍歷模式陌兑。在“'polls/'”中找到匹配后沈跨,它去掉了匹配的文本(“polls/”),并將剩下的文本——“34/” 發(fā)送到 “polls.urls”诀紊。用于進(jìn)一步處理的url URLconf谒出。在那里它與<int:問題id/'相匹配,導(dǎo)致對detail()視圖的調(diào)用如下:
detail(request=<HttpRequest object >,question_id=34)
寫一些實(shí)際做某事的視圖
每個(gè)視圖負(fù)責(zé)執(zhí)行以下兩件事之一:返回一個(gè)包含所請求頁面的內(nèi)容的?HttpResponse?邻奠,或者提出一個(gè)異常笤喳,如Http404。其余的由你決定碌宴。
All Django wants is that?HttpResponse. Or an exception.
因?yàn)樗芊奖闵苯疲宰屛覀兪褂肈jango自己的數(shù)據(jù)庫API,這里有一個(gè)index()視圖贰镣,它顯示了系統(tǒng)中最新的5個(gè)輪詢問題呜象,根據(jù)發(fā)布日期:
不過這里有一個(gè)問題:頁面的設(shè)計(jì)在視圖中是硬編碼的膳凝。如果您想要改變頁面的外觀,您將不得不編輯這個(gè)Python代碼恭陡。因此蹬音,讓我們使用Django的模板系統(tǒng)來將設(shè)計(jì)從Python中分離出來,創(chuàng)建一個(gè)視圖可以使用的模板
First, create a directory called?templates?in your?polls?directory. Django will look for templates in there.
您的項(xiàng)目的TEMPLATES設(shè)置描述了Django如何加載和呈現(xiàn)模板休玩。默認(rèn)設(shè)置文件配置一個(gè)DjangoTemplates后端著淆,其APP_DIRS?選項(xiàng)被設(shè)置為True。按照慣例拴疤,DjangoTemplates在每個(gè)INSTALLED_APPS.中尋找一個(gè)“templates”子目錄永部。
在剛剛創(chuàng)建的templates目錄中,創(chuàng)建名為poll的另一本目錄呐矾,并在其中創(chuàng)建名為index.html的文件苔埋。換句話說,您的模板應(yīng)該是polls/templat/polls/index.html蜒犯。由于appdirectory模板加載器是如何工作的组橄,所以您可以在Django中引用這個(gè)模板,就像polls/index.html一樣罚随。
polls/templates/polls/index.html
Now let’s update our?index?view in?polls/views.py?to use the template:
polls/views.py
該代碼加載名為polls/index的模板晨炕。html并傳遞一個(gè)上下文。上下文是將模板變量名映射到Python對象的字典毫炉。
通過將瀏覽器指向 “/polls/” 來加載頁面,您應(yīng)該會看到一個(gè)包含“What’s up”問題的列表削罩,鏈接指向問題的詳細(xì)頁面瞄勾。
A shortcut:?render()
加載模板、填充上下文并返回一個(gè)帶有渲染模板的結(jié)果的HttpResponse?對象是一個(gè)非常常見的習(xí)慣弥激。Django提供了一個(gè)捷徑进陡。這是完整的index()視圖,重寫:
render()函數(shù)把request對象作為它的第一個(gè)參數(shù)微服,一個(gè)模板名作為第二個(gè)參數(shù)趾疚,而字典作為它的可選的第三個(gè)參數(shù)。它返回給定模板呈現(xiàn)的給定模板的一個(gè)HttpResponse?體對象
Raising a 404 error
Now, let’s tackle the question detail view – the page that displays the question text for a given poll. Here’s the view:
polls/views.py
The new concept here: The view raises the?Http404?exception if a question with the requested ID doesn’t exist.
We’ll discuss what you could put in that?polls/detail.html?template a bit later, but if you’d like to quickly get the above example working, a file containing just:
polls/templates/polls/detail.html
A shortcut:?get_object_or_404()
如果對象不存在以蕴,那么使用get()并提高Http404是一個(gè)非常常見的習(xí)慣糙麦。Django提供了一個(gè)捷徑。這里的細(xì)節(jié)()看來,重寫:
get_object_or_404()?函數(shù)接受Django模型作為它的第一個(gè)參數(shù)和任意數(shù)量的關(guān)鍵字參數(shù)丛肮,它傳遞給model的manager的get()函數(shù)赡磅。如果對象不存在,它就會提高Http404宝与。
為什么我們要使用一個(gè)助手函數(shù)getobjector404()而不是在更高的級別上自動捕獲objectnotexist異常焚廊,或者讓模型API提高Http404而不是objectdo notexist冶匹?
因?yàn)檫@會將模型層與視圖層耦合。Django最重要的設(shè)計(jì)目標(biāo)之一就是保持松散耦合咆瘟。在django中引入了一些控制耦合嚼隘。快捷鍵模塊袒餐。
使用模板系統(tǒng)
模板系統(tǒng)使用點(diǎn)查找語法來訪問可變屬性飞蛹。在這個(gè)問題的例子中。問題文本匿乃,首先Django對對象問題進(jìn)行字典查找桩皿。如果失敗了,它會嘗試一個(gè)屬性查找——在這種情況下是可行的幢炸。如果屬性查找失敗了泄隔,它將嘗試一個(gè)列表索引查找。
在模板中刪除硬編碼的url
記住宛徊,當(dāng)我們在投票/索引中寫下一個(gè)問題的鏈接時(shí)佛嬉。html模板,這個(gè)鏈接部分是硬編碼的:
這種硬編碼的闸天、緊密耦合的方法的問題在于暖呕,在帶有大量模板的項(xiàng)目上更改url變得很有挑戰(zhàn)性。但是苞氮,因?yàn)槟趐olls.urls模塊 中定義了path()函數(shù)中的name參數(shù)湾揽。您可以通過使用 {%?url?%} 模板標(biāo)簽來消除對URL配置中定義的特定URL路徑的依賴:
命名空間網(wǎng)址名稱
項(xiàng)目只有一個(gè)應(yīng)用,即polls笼吟。在真正的Django項(xiàng)目中库物,可能有5個(gè)、10個(gè)贷帮、20個(gè)應(yīng)用程序或更多戚揭。Django如何區(qū)分它們之間的URL名稱?例如撵枢,polls應(yīng)用程序有一個(gè)詳細(xì)的視圖民晒,同樣的項(xiàng)目也可以在同一個(gè)項(xiàng)目中使用。如何讓Django知道在使用 { %?url?%} 模板標(biāo)簽時(shí)為url創(chuàng)建哪個(gè)應(yīng)用程序視圖锄禽?
Now change your?polls/index.html?template from:
to point at the namespaced detail view: