基于Django类的视图组合

基于Django类的视图组合,django,view,composite,django-class-based-views,Django,View,Composite,Django Class Based Views,我正在为一个项目使用Django 1.3的类基类通用视图。他们真的很好,但我想成为干衣机。我有一个页面显示我们收到的新闻报道列表,另一个页面显示我们发表的文章列表。在概览页面上,我需要显示两个列表。我想创建一个复合视图,该视图接受两个视图并创建一个附加了两个查询集的上下文。是否可以覆盖get\u context\u data方法以向上下文添加其他数据 def get_context_data(self, **kwargs): context = super(AuthorLis

我正在为一个项目使用Django 1.3的类基类通用视图。他们真的很好,但我想成为干衣机。我有一个页面显示我们收到的新闻报道列表,另一个页面显示我们发表的文章列表。在概览页面上,我需要显示两个列表。我想创建一个复合视图,该视图接受两个视图并创建一个附加了两个查询集的上下文。

是否可以覆盖get\u context\u 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\u list}
{{articles\u list}}

获得新闻列表和文章列表。在我看来,视图只是一页。视图可以有多种形式,我认为在您的示例中,这是一个更好的解决方案

只需将模板拆分为几个文件,每个表单都有一个小模板,并使用template include指令将其缝合在一起。这还有一个额外的优点,即表单可以在其他视图中非常简单地重用


您的解决方案基本上类似于框架,但在服务器上而不是在浏览器中。

简单的方法:

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)
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,)

    ]
不要在两个queryset上手动使用常规视图和对象

它不会那么长,也不会有什么线路会让你的干涸

通用但漫长的道路:

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)
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,)

    ]
创建一个视图,将
\uuuu init\uu
\uu和
get\u context
方法包装起来,以将参数传递给两个ListView实例

init应该实例化这两个
ListView
,传递参数并将实例添加到包装器的属性中

get\u context
应该调用这两个get\u context列表视图实例方法,并将它们合并到一个context对象中

确保为每个
列表视图
设置不同的
模板\u对象\u名称
,这样它们就不会在上下文dict中相互覆盖

用一种通用的方法来做这件事,别忘了用pusblish编写代码:-)

我们可以通过执行以下操作来实现这一点:

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)
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,)

    ]
视图。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)
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,)

    ]

你应该回答自己的问题,而不是更新你的帖子。这样,社区一眼就能看出有一个解决方案,它是什么。当我开始使用Django时,我发现通用视图几乎是所有东西的工具。我修改、修补并修复了它,以满足我的需求。问题是,这不是他们正在解决的问题。一旦你超出了他们的预期范围,就用普通视图来代替。@Dave我将Kenzic的解决方案移动到了一个答案中,并标记了该答案,希望版主将其归因于Kenzic而不是我。如果你不想因为某人的答案而赢得rep,那么你可以将其切换到CW。此外,两个月过去了,肯齐奇还没有找到答案;其他人介入并给出正确答案是合理的。