Композитный вид на основе 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: -)