Композитный вид на основе Django
Я использую общие представления класса Django 1.3 для проекта. Они очень хорошие, но я хотел бы быть DRYer. У меня есть страница, на которой отображается список прессов, которые мы получили, а другой - список статей, которые мы опубликовали. На обзорной странице мне нужно отобразить оба списка. Я хотел бы создать составной вид, который принимает оба представления и создает контекст с присоединенными наборами запросов.
Ответы
Ответ 1
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,)
]
Ответ 2
Может быть, вы можете переопределить метод 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 }}
.
Ответ 3
На мой взгляд, представление - это просто одна страница. Представление может иметь несколько форм, которые, я думаю, являются лучшим решением в вашем примере.
Просто разделите шаблон на несколько файлов, где каждая форма имеет небольшой шаблон, и используйте шаблон include, чтобы сшить его вместе. Это также имеет дополнительное преимущество, что форма может быть повторно использована в других представлениях очень просто.
Ваше решение в основном похоже на фреймы, но на сервере, а не в браузере.
Ответ 4
Простой способ:
Не используйте общий вид и объект paginator вручную на обоих запросах.
Это будет не так долго, и это не некоторые строки, которые собираются убить вашу СУХУЮ ИМО.
Общий, но длинный путь:
Создайте представление, которое обертывает методы __init_
_ и get_context
для передачи аргумента двум экземплярам ListView.
init должен инициализировать как ListView
, передать параметры и добавить экземпляры в атрибуты обертки.
get_context
должен вызвать оба метода get_context Listview и объединить их в один объект контекста.
Обязательно настройте другой template_object_name
для каждого ListView
, чтобы они не переопределяли друг друга в контексте dict.
Сделайте это в общем виде и не забудьте перфорировать код на djangosnippet: -)