Django 之 基於類的視圖源碼分析

基於類的視圖(Class-based view)是Django 1.3引入的新的視圖編寫方式,用於取代之前基於函數(Function-based)方式。 藉助於OO和Python中方便的多重繼承特性,基於類的視圖能夠提供更好的抽象與複用能力。 新的通用視圖將更加優雅。 html

Django的文檔較爲豐富,但在實際開發中每每仍顯得不夠,不少時候仍是須要深刻到源代碼當中一探究竟。爲此,仔細整理了一下基於類的視圖的實現方式。指望對之後的開發可以提供更加清晰、直接的參考。 算法

說明: Django大量應用了多重繼承特性。將一些通用的功能性代碼拆分混入類(Mixin),須要這些混入類的代碼時,只須要將混入類加入到類的繼承列表中便可——請注意順序,左側的類具備較高權限,將覆蓋右側繼承類中的同名函數。爲了說明方便,將這些混入類(Mixin)成爲"工具類"。 django

源碼組織

全部的視圖相關代碼,均存放與django/views/generic目錄中: app

  • base.py 保存視圖的抽象類,TemplateView和RedirectView,及工具類TemplateResponseMixin的代碼 函數

  • create_update.py 基於函數的通用視圖。已標記爲deprecated 工具

  • date_based.py 基於函數的日期相關通用視圖。已標記爲deprecated 源碼分析

  • dates.py 新的基於類的日期相關通用視圖。用於取代date_based.py post

  • detail.py 基於類的單個對象顯示相關的視圖和工具類 url

  • edit.py 基於類的對象編輯相關的視圖和工具類 spa

  • list.py 基於類的對象列表顯示相關視圖和工具類

  • list_detail.py 基於函數的列表、顯示函數。已標記爲deprecated

  • simply.py 基於函數的工具經常使用工具試圖。已標記爲deprecated

從邏輯上來看,源代碼被組織爲抽象基類,工具類(Mixin),常規(具體)實現和基於模型的實現。

源碼分析

抽象類和經常使用視圖(base.py)

這個文件包含視圖的頂級抽象類(View),基於模板的工具類(TemplateResponseMixin),模板視圖(TemplateView)和重定向視圖(RedirectView)。

View及View的執行順序

View是全部基於類的視圖的基類。僅實現了一些基本的方法和必要的檢查工做。其中最重要的是dispatch方法。再次方法中,根據HTTP請求中的method參數,調用相應的同名處理函數。這裏留下了一個口子,後續的類須要根據本身的狀況來填補這個口子最終完成一個視圖的處理。

  • 屬性

  • httpmethodnames 定義全部的Http metho['get','post','put','delete','head','options','trace']。

  • 方法

  • init 初始化方法

由URLConf調用。包含將關鍵字參數存入實例屬性等功能。

若是一個視圖包含一個實例屬性,且在urlpattern中設置了相應的值。將配置的值賦給視圖對象的方法就是由URLConf調用init函數時做爲參數傳入。View.init負責具體的賦值工做。

  1. as_view 類方法(classonlymethod)。返回Function-based視圖函數對象。返回的視圖函數對象("在被調用時")負責實例化視圖,調用視圖的dispatch方法。

  2. dispatch 調度函數。根據Http method調用視圖的同名函數

  3. httpmethodnot_allowed 返回不被容許的http method處理函數

TemplateResponseMixin

提供使用模版渲染的工具類。template_name參數用於指定模版。但願具有模版功能的視圖能夠直接繼承此工具累計可。不過咱們不多直接在本身的視圖中繼承此工具類,由於Django已經提供了一組有用的視圖來減小咱們的工做。

TemplateView

基於模版的視圖 。須要提供附加數據,能夠在繼承此視圖的子類中,重寫getcontextdata方法。經常使用於諸如"about","copyrights" ,"terms"等基於文本的靜態內容。只需設置template_name便可。甚至直接能夠在URLConf中直接指定此參數。

如:


1 url(r'^about/$',TemplateView.as_view(template_name='about.html'))

RedirectView

重定向視圖。能夠說這個視圖提供了徹底的重定向功能。不管是http get、post、delete仍是head、options都將重定向到url參數指定的地址。

permanent 屬性指定是否返回永久(HTTP 301)重定向信息,不然返回臨時重定向(HTTP 302),默認是true.

列表類通用視圖(list.py)

此文件包含用於顯示數據列表經常使用的類和工具類。不只能夠方便的用於顯示基於模型(Model)的數據列表,也能夠用於顯示自定義數據列表。

此圖中綠色部分屬於base.py,引入此圖中是爲了說明他們之間的關係

MultipleObjectMixin

最主要的核心工具類,主要的算法和接口所有都在這個工具類中實現。

  • 屬性

allow_empty 默認值True。表示沒有數據時顯示空列表;不然將會產生一個404錯誤。

queryset 產生數據的queryset實例或"類queryset"數據列表。

model 關聯的模型類。

paginated_by 分頁的每頁數據項數。默認不起用分頁。

contextobjectname 保存到context中的對象名稱。默認是$(model)_list。

paginator_class 默認值Paginator。分頁處理器。

  • 方法

get_queryset 獲取用於數據顯示的列表對象。能夠是類queryset對象。此方法優先選擇使用queryset屬性。未提供queryset屬性時,返回model的默認管理器。若是也沒有提供model屬性,將會產生ImproperlyConfigured異常。

paginatequeryset 根據須要,將queryset分頁。返回(paginator, page, page.objectlist, page.hasotherpages())

getpaginateby 返回每頁數據項數。None表示不分頁。

get_paginator 返回分頁器

getallowempty 參見allow_empty屬性說明

getcontextobjectname 參見contextobject_name屬性說明

getcontextdata 設置視圖的附加屬性。一般重寫此方法來爲視圖提供附加數據。 默認設計的視圖數據:

'paginator': 分頁器, 'page_obj': 頁對象, 'is_paginated': 是否進行了分頁, 'object_list': 視圖的數據

*BaseListView*

視圖列表基類。繼承自MutipleObjectMixin和View。這是一個抽象類。此函數經過增長get方法來整合View的處理流程和MutipleObjectMixin提供的工具函數。

MultipleObjectTemplateResponseMixin

繼承自TemplateResponseMixin,並重寫gettemplatenames方法。追加$(applabel)/$(model)list.html做爲默認模板。

ListView

本模塊功能集大成者。通常都是直接繼承此類,並重寫MutipleObjectMixin的一些默認屬性和/或方法來實現需求。

此類繼承自MultipleObjectTemplateResponseMixin和BaseListView。通常來講,只需提供model屬性,並編寫$(model)list.html便可實現數據列表功能。如需分頁能夠重寫paginatedby屬性,指定每頁數據項數目。

相關文章
相關標籤/搜索