2011-04-21 160 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