2011-04-21 441 views
13

我對項目使用Django 1.3的基於類的基類視圖。他們非常好,但我想成爲DRYer。我有一個頁面顯示我們收到的新聞報道列表,另一個顯示我們發佈的文章列表。在概覽頁面上,我需要顯示這兩個列表。我想創建一個複合視圖,該視圖接受兩個視圖並創建一個包含兩個附加查詢集的上下文。Django基於類的視圖複合

+2

而不是更新您的帖子,你應該回答你自己的問題。通過這種方式,社區可以一目瞭然地知道有一個解決方案,它是什麼。 – Dave 2011-09-26 10:19:11

+0

當我開始使用Django時,我開始發現通用視圖是幾乎所有東西的工具。我修改,修補,並修復,以做我想要的。問題是,那不是他們正在解決的問題。一旦你超越了它們的目標限制,只需使用普通視圖。 – 2011-10-03 22:10:43

+0

@Dave我將Kenzic的解決方案轉化爲答案,並標記答案,希望版主將它歸於Kenzic而不是我。 – akaihola 2011-11-28 07:45:49

回答

0

也許你可以重寫get_context_data方法來將其他數據添加到上下文中?

def get_context_data(self, **kwargs): 

     context = super(AuthorListView, self).get_context_data(**kwargs) 
     # Add in a QuerySet of all the books 
     context['press_list'] = Press.objects.all() 
     context['articles_list] = Article.objects.all() 
     return context 

,並在您的模板,你可以得到新聞列表,並使用{{ press_list }}{{ articles_list }}文章列表。

0

在我看來,一個視圖只是一個頁面。一個視圖可以有多種形式,我認爲這是您示例中更好的解決方案。

只需將模板分成幾個文件,其中每個表單都有一個小模板,然後使用模板include指令將它們拼接在一起。這還具有附加的優點,即表單可以在其他視圖中重複使用,非常簡單。

您的解決方案基本上像框架,但在服務器上而不是在瀏覽器中。

0

最簡單的方法:

不要在這兩個查詢集手動使用一個通用的視圖和paginator對象。

這段時間不會那麼長,也不是某些行會幹掉你的DRY IMO。

通用的,但很長的路要走:

創建包裹__init_ _和get_context方法來傳遞參數,兩個ListView控件實例的視圖。

init should instanciate both ListView,傳遞參數並將實例添加到包裝的屬性。

get_context應調用get_context Listview實例方法,並將它們合併到一個上下文對象中。

請務必爲每個ListView設置不同的template_object_name,以便它們在上下文字典中不會互相覆蓋。

做,在一個通用的方法,並且不要忘記pusblish上djangosnippet :-)

4

Kenzic能夠通過執行以下操作來實現這一點,你的代碼:

composite.py:

from django.views.generic.base import TemplateResponseMixin, View 

class BaseCompositeView(TemplateResponseMixin, View): 

    composite_views = [] 

    def get_composite_views(self): 
     return self.composite_views 

    def get_context_data(self, request, *args, **kwargs): 
     context = {} 
     composite_views = self.get_composite_views() 
     for composite_view in composite_views: 
      cls = composite_view[0] 
      try: 
       clsview = cls.as_view(**composite_view[1]) 
      except IndexError: 
       clsview = cls.as_view() 

      view = clsview(request, *args, **kwargs) 
      context_data = view.context_data 
      context.update(context_data) 

     return context 

    def get(self, request, *args, **kwargs): 
     context = self.get_context_data(request, *args, **kwargs) 
     return self.render_to_response(context) 

views.py:

from django.views.generic import TemplateView, ListView, DetailView 
from composite import BaseCompositeView 
from .models import * 


class MediaCoverageList(ListView): 
    queryset = MediaCoverageItem.objects.order_by('-date') 


class PressKitList(ListView): 
    queryset = PressKit.objects.all() 


class NewsroomLanding(BaseCompositeView): 
    template_name = 'newsroom/landing.html' 
    composite_views = [ 
     (MediaCoverageList,{ 
      'paginate_by': 10, 
     },), 
     (PressKitList,) 

    ] 
+5

如果您不想因某人的回答而獲得代表權,則可以將其切換爲CW。此外,兩個月過去了,Kenzic沒有創造答案;其他人介入並提供正確答案是合理的。 – casperOne 2011-11-28 14:38:54