基于Django类的视图组合
我正在为一个项目使用Django 1.3的类基类通用视图。他们真的很好,但我想成为干衣机。我有一个页面显示我们收到的新闻报道列表,另一个页面显示我们发表的文章列表。在概览页面上,我需要显示两个列表。我想创建一个复合视图,该视图接受两个视图并创建一个附加了两个查询集的上下文。是否可以覆盖get\u context\u data方法以向上下文添加其他数据基于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
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。此外,两个月过去了,肯齐奇还没有找到答案;其他人介入并给出正确答案是合理的。