我正在为一个项目使用 Django 1.3 的基于类的通用视图。他们真的很好,但我想成为 DRYer。我有一个页面显示我们收到的新闻报道列表,另一个页面显示我们已发布的文章列表。在概述页面上,我需要显示两个列表。我想创建一个复合视图,它接受两个视图并创建一个附加了两个查询集的上下文。
4 回答
Kenzic能够通过执行以下操作来实现此目的:
复合.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)
视图.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,)
]
也许您可以覆盖 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 }}
。
在我看来,视图只是一页。一个视图可以有多种形式,我认为在您的示例中这是一个更好的解决方案。
只需将模板拆分为多个文件,其中每个表单都有一个小模板,然后使用模板包含指令将其拼接在一起。这还有一个额外的好处,即表单可以非常简单地在其他视图中重用。
您的解决方案基本上类似于框架,但在服务器上而不是在浏览器中。
简单的方法:
不要在两个查询集上手动使用通用视图和分页器对象。
它不会那么长,也不会是一些台词会杀死你的 DRY IMO。
通用但很长的路要走:
创建一个包装__init_
_ 的视图和get_context
将参数传递给两个 ListView 实例的方法。
init应该实例化两者ListView
,传递参数并将实例添加到包装器的属性中。
get_context
应该调用这两个 get_context Listview 实例方法,并将它们合并到一个上下文对象中。
确保template_object_name
为每个设置不同的,ListView
这样它们就不会在上下文字典中相互覆盖。
以通用方式执行此操作,并且不要忘记在 djangosnippet 上发布您的代码:-)