Django 基於類的通用視圖


在早期,我們認識到在視圖開發過程中有共同的用法和模式。這時我們引入基於函數的通用視圖來抽象這些模式以簡化常見情形的視圖開發。

基於函數視圖的用法有以下三種:

def index(request): return HttpResponse('hello world!') def index(request): result = {'demo':'demo'} return render(request, 'blog/about.html', result) def index(request): result = {'demo':'demo'} return render_to_response('blog/about.html', result) 

基於函數的視圖的問題在於,雖然它們很好地覆蓋了簡單的情形,但是不能擴展或自定義它們,即使是一些簡單的配置選項,這讓它們在現實應用中受到很多限制。基於類的通用視圖然后應運而生,目的與基於函數的通用視圖一樣,就是為了使得視圖的開發更加容易。

下面三個是最常使用的基於類的通用視圖:

TemplateView,ListView,DetailView

TemplateView

TemplateView 一般只在需要返回模板時使用。

class ProtectView(TemplateView): template_name = 'polls/name.html' 

TemplateView 可以方便的定義要返回的模板但它不能把數據庫中的內容查詢展示出來,所以需要使用 DetailViewListView

所有基於類的通用視圖中定義的方法需要在類視圖調用 as_view() 方法后會被自動調用,因為 DjangoURL 解析器將請求和關聯的參數發送給一個可調用的函數而不是一個類,所以基於類的視圖有一個 as_view() 類方法用來作為類的可調用入口。

ListView

ListView 用於獲取存儲在數據庫中的某個 Model 的列表。

class IndexView(ListView): """ 首頁視圖函數,繼承 ListView ,展示從數據庫中獲取的文章列表 """ template_name = "blog/index.html" context_object_name = "article_list" model = Article 

template_name 屬性指定了需要渲染的模板,context_object_name 指定了模板中使用的上下文變量,model 指定了數據的來源。它的功能相當於取出了 modelArticle 的所有數據,使用變量 article_list 傳遞給了 blog/index.html 模板。ListView 中默認使用 object_list 作為上下文變量,可以使用 context_object_name 來自定義上下文變量,一般使用默認的對模板設計者不友好,所以都是自定義上下文變量的。model 屬性指定了要獲取表中的所有數據,它的功能相當於 article_list = Article.objects.all(),但是當你需要使用過濾條件或者對數據進行一定的操作時,則需要重寫 ListView 中獲取數據的方法(get_queryset 方法),像下面這樣:

class IndexView(ListView): """ 首頁視圖函數,繼承 ListView ,展示從數據庫中獲取的文章列表 """ template_name = "blog/index.html" context_object_name = "article_list" def get_queryset(self): """ 重寫 get_queryset 方法,取出發表的文章並轉換文章格式 """ article_list = Article.objects.filter(status='p') for article in article_list: article.body = markdown2.markdown(article.body, extras=['fenced-code-blocks'], ) return article_list def get_context_data(self, **kwargs): kwargs['category_list'] = Category.objects.all().order_by('name') return super(IndexView, self).get_context_data(**kwargs) 

此次重寫了 get_context_data 方法,這個方法是用來添加額外的內容傳遞到模板文件的上下文對象(context)中。上面的例子中將 category_list 添加到上下文變量中,則在模板中可以使用 {{ }} 來展示 category_list 中的內容。

ListView 主要用來獲取某個 model 中的所有數據,通過 template_name 屬性來指定需要渲染的模板,通過 context_object_name 屬性來指定上下文變量(默認為 object_list),通過重寫 get_queryset 方法來對 model 中的數據增加其他邏輯,通過重寫 get_context_data 方法來為上下文對象添加額外的對象。

DetailView

ListView 用來獲取某個 model 中的所有數據,而 DetailView 則是獲取每個數據的詳細信息,比如 ListView 獲取所有文章列表,DetailView 用來獲取文章的詳細信息。

class ArticleDetailView(DetailView): """ 文章詳情頁 """ model = Article template_name = 'blog/detail.html' context_object_name = "article" # 在 urlpattern 中定義的 pk_url_kwarg = 'article_id' def get_object(self, queryset=None): """ 獲取對應文章的信息 """ obj = super(ArticleDetailView, self).get_object() obj.body = markdown2.markdown(obj.body, extras=['fenced-code-blocks'], ) return obj # 增加 form 到 context def get_context_data(self, **kwargs): kwargs['comment_list'] = self.object.blogcomment_set.all() #獲取評論 return super(ArticleDetailView, self).get_context_data(**kwargs) 

pk_url_kwarg 定義用來獲取對應的單條數據,需要傳遞主鍵的值。get_object 方法獲取 pk_url_kwarg 中所要查找的對象,類似於 ListView 中的 get_queryset 方法,get_context_data 方法和 ListView 中的功能相同。

DetailView 主要用在獲取某個 model 的單個對象中,需要在 URL 中傳遞一個主鍵值進行查詢。



作者:田飛雨
鏈接:https://www.jianshu.com/p/6d6c890f5f72
來源:簡書


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM