プロジェクトに Django 1.3 のクラスベースのジェネリック ビューを使用しています。彼らは本当に素晴らしいですが、私はもっとドライになりたいです. 受け取った報道のリストを表示するページと、公開した記事のリストを表示するページがあります。概要ページでは、両方のリストを表示する必要があります。両方のビューを受け入れ、両方のクエリセットが添付されたコンテキストを作成する複合ビューを作成したいと思います。
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,)
]
簡単な方法:
両方のクエリセットで汎用ビューとpaginatorオブジェクトを手動で使用しないでください。
それはそれほど長くはないでしょう、そしてそれはあなたのDRYIMOを殺そうとしているいくつかの行ではありません。
一般的ですが長い道のり:
__init_
_メソッドとメソッドをラップするビューを作成して、get_context
2つのListViewインスタンスに引数を渡します。
initは両方ListView
をインスタンス化し、パラメーターを渡し、ラッパーの属性にインスタンスを追加する必要があります。
get_context
両方のget_contextListviewインスタンスメソッドを呼び出し、それらを1つのコンテキストオブジェクトにマージする必要があります。
コンテキストディクテーションで相互にオーバーライドしないように、必ずtemplate_object_name
それぞれに異なる設定を行ってください。ListView
一般的な方法でそれを行い、djangosnippetのコードをpusblishすることを忘れないでください:-)
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 }}
。
私の考えでは、ビューは単なる 1 ページです。ビューにはいくつかのフォームがありますが、これはあなたの例ではより良い解決策だと思います。
テンプレートをいくつかのファイルに分割し、各フォームには小さなテンプレートがあり、テンプレート インクルード ディレクティブを使用してそれらをつなぎ合わせます。これには、フォームを他のビューで非常に簡単に再利用できるという利点もあります。
あなたのソリューションは基本的にフレームに似ていますが、ブラウザではなくサーバー上にあります。