深入Django(1): 通用视图 (generic views)
如果對(duì)Django的基礎(chǔ)部分尚不熟悉,請(qǐng)參考《Django實(shí)戰(zhàn)》系列。
內(nèi)容提要
1. 回顧Django的視圖函數(shù)(view function)
2. 在視圖函數(shù)中使用模板
3. 簡(jiǎn)化視圖函數(shù)的兩個(gè)工具
4. 使用通用視圖函數(shù)
5. Django提供的通用視圖
1. 回顧Django的視圖函數(shù)(view function)
Django中將視圖定義為一種函數(shù),我們稱(chēng)其為視圖函數(shù)(view function)。當(dāng)Django框架接收到http請(qǐng)求的時(shí)候,從定義的urlpatterns中尋找url表達(dá)式進(jìn)行匹配,一旦找到匹配的項(xiàng),就將HTTPRequest以及匹配到的其他字符串作為參數(shù),調(diào)用找到的視圖函數(shù),然后根據(jù)視圖函數(shù)返回的HTTPResponse對(duì)象進(jìn)行響應(yīng)。所以視圖函數(shù)應(yīng)該至少接收一個(gè)django.http.HTTPRequest對(duì)象作為參數(shù),并返回django.http.HTTPResponse對(duì)象,如下:
def my_view(request, *args, **kwargs): response = HTTPResponse() … ... return response
?
2. 在視圖函數(shù)中使用模板
視圖函數(shù)返回的response對(duì)象中包含一些頭(Header)信息和內(nèi)容(Content),而我們通常通過(guò)模板來(lái)生成內(nèi)容,所以我們經(jīng)常用到的視圖函數(shù)應(yīng)該是這樣:
?
def my_view_with_template(request, *args, **kwargs): var1 = foo var2 = bar t = get_template('path_name_of_template_file') c = Context({'key1':var1,'key2':var2}) content = t.render( c) return HTTPResponse(content)
?
3. 簡(jiǎn)化視圖函數(shù)的兩個(gè)工具
總是寫(xiě)這樣的代碼實(shí)在是讓人厭倦,所以Django為我們提供了兩個(gè)有用的工具:
一個(gè)是django.shortcuts.render_to_response函數(shù),接收一系列的參數(shù),包括模板路徑、context使用的字典、原始的context實(shí)例以及要設(shè)定的mimetype等:
???? render_to_response(template_path_name, dictionary=None, context_instance=None, mimetype=None)
另一個(gè)是locals()函數(shù),將所有的局部變量組裝成一個(gè)字典。
有了這兩個(gè)工具,視圖函數(shù)就可以這樣寫(xiě):
def my_view_with_template(request, *args, **kwargs): var1 = foo var2 = bar return render_to_response('path_name_of_template_file', locals())
?
4. 使用通用視圖函數(shù)
有了這兩個(gè)工具,編寫(xiě)視圖函數(shù)確實(shí)可以簡(jiǎn)化很多。但是這樣你就滿意了嗎?Django并沒(méi)有就此止步,更進(jìn)一步注意到,很多視圖函數(shù)其實(shí)都在做同樣的事情,比如顯示一組模型對(duì)象的列表,顯示模型對(duì)象的詳細(xì)信息,對(duì)模型對(duì)象的增、刪、改操作等。為了簡(jiǎn)化對(duì)這些情況的處理,Django定義了一系列的通用視圖(generic views),我們只需要使用這些內(nèi)置的通用視圖函數(shù),而無(wú)需自己編寫(xiě)就可以實(shí)現(xiàn)相應(yīng)的功能。
使用通用視圖的方法是在URLconf文件中創(chuàng)建參數(shù)字典,將字典作為URLconf元組的第三個(gè)成員,即可自動(dòng)在調(diào)用視圖函數(shù)時(shí)向其傳遞參數(shù)了。比如在django.views.generic.list_detail模塊中的object_list函數(shù),用于顯示模型對(duì)象的列表,可以接受queryset參數(shù)作為模型對(duì)象的結(jié)果集。如果我們要用該視圖函數(shù)顯示在《Django實(shí)戰(zhàn)》系列中的創(chuàng)建的第一個(gè)模型類(lèi)Product的列表,可以在URLconf中這樣配置:
from django.conf.urls.defaults import * from django.views.generic import list_detail from depot.depotapp.models import Product product_info = { 'queryset': Product.objects.all(), } urlpatterns = patterns('', (r'^product/list/$', list_detail.object_list, product_info) )
?
除了queryset外,object_list函數(shù)還可以接收許多其他的參數(shù):
?
object_list(request, queryset, paginate_by=None, page=None, allow_empty=True, template_name=None, template_loader=loader, extra_context=None, context_processors=None, template_object_name='object', mimetype=None )
?
通用視圖函數(shù)接收到參數(shù)后,會(huì)創(chuàng)建context,并渲染模板,最后返回HTTPResponse對(duì)象。object_list函數(shù)創(chuàng)建的context中會(huì)包含以下字典項(xiàng):
? object_list???????????? 要顯示的對(duì)象的list
? is_paginated???????? 是否分頁(yè)
? results_per_page 如果分頁(yè),存儲(chǔ)每頁(yè)記錄數(shù)
? has_next????????????? 是否有下一頁(yè)
? has_previous?????? 是否有上一頁(yè)
? page???????????????????? 當(dāng)前頁(yè)碼
? next????????????????????? 下一頁(yè)
? previous?????????????? 上一頁(yè)
? pages?????????????????? 總頁(yè)數(shù)
? hits?????????????????????? 總條目數(shù)
? last_on_page?????? 本頁(yè)最后錄一條記錄的序數(shù)(從1開(kāi)始)
? first_on_page?????? 本頁(yè)第一條記錄的序數(shù)(從1開(kāi)始)
? page_range????????? 頁(yè)碼范圍的列表
如果這些context字典項(xiàng)不能滿足你的需要,還可以通過(guò)指定extra_context參數(shù),傳入一個(gè)字典,該字典中的內(nèi)容會(huì)被合并到context字典中。
context字典項(xiàng)會(huì)被模板使用。如果不指定模板,該函數(shù)將使用[app_name]/[model_name]_list.html作為模板,指定模板的方法也是通過(guò)參數(shù)字典,比如:
product_info = { 'queryset': Product.objects.all(), 'template_name': 'depotapp/another_product_list.html'), ?}
這個(gè)參數(shù)字典會(huì)傳入template_name參數(shù)來(lái)指定渲染的模板文件。
5. Django提供的通用視圖
除了object_list外,Django還提供了許多通用視圖函數(shù),分布在幾個(gè)模塊中:
django.views.generic.list_detail模塊
- object_list????? 顯示模型對(duì)象列表???
- object_detail? 顯示單個(gè)模型對(duì)象
django.views.generic.create_update模塊
- create_object??? 創(chuàng)建模型對(duì)象
- update_object?? 修改模型對(duì)象
- delete_object??? 刪除模型對(duì)象
django.views.generic.simple模塊
- direct_to_template?? 直接使用指定的模板渲染給定的context對(duì)象
- redirect_to?? 重定向到指定的url
django.views.generic.date_based模塊
這個(gè)模塊主要處理“按時(shí)間查看存檔”的功能,來(lái)源于新聞出版行業(yè)。具體包括:
- archive_index?? 最頂級(jí)的歸檔,列出所有年份及指定數(shù)量的最新對(duì)象
- archive_year???? 按年歸檔,列出所有擁有對(duì)象的月份
- archive_month?? 按月歸檔,列出本月的所有對(duì)象,找到擁有對(duì)象的上一個(gè)、下一個(gè)月份
- archive_week???? 按周歸檔,列出本周的所有對(duì)象
- archive_day???? 按日歸檔,列出當(dāng)天的所有對(duì)象,找到擁有對(duì)象的上一個(gè)、下一個(gè)日期
- archive_today???? 當(dāng)前日期(今天)的按日歸檔
- object_detail???? 顯示按照年/月/日/序號(hào)找到的對(duì)象
這些通用視圖函數(shù)不再一一介紹,可以參考Django API文檔,關(guān)注其參數(shù),context內(nèi)容和默認(rèn)模板,就能基本掌握其使用。
總結(jié)
以上是生活随笔為你收集整理的深入Django(1): 通用视图 (generic views)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: OCP Java 自测
- 下一篇: JavaScript 正则表达式(Reg