2011-04-21 11 views
13

Estoy utilizando las vistas genéricas de clase de Django 1.3 para un proyecto. Son muy amables, pero me gustaría ser DRYer. Tengo una página que muestra una lista de la cobertura de prensa que hemos recibido y otra que muestra una lista de artículos que hemos publicado. En la página de resumen, necesito mostrar ambas listas. Me gustaría crear una vista compuesta que acepte ambas vistas y cree un contexto con ambos querysets conectados.Django Class Based View Composite

+2

En lugar de actualizar su publicación, debe responder su propia pregunta.De esta forma, la comunidad puede ver de un vistazo que hay una solución y qué es. – Dave

+0

Cuando comencé con Django comencé a encontrar las vistas genéricas como la herramienta para casi todo. Modifiqué, parcheé y arreglé eso para hacer lo que quería. El problema era que eso no es lo que están resolviendo. Tan pronto como sobrepase el límite para el que están destinados, simplemente use una vista normal. –

+0

@Dave Cambié la solución de Kenzic a una respuesta y marqué la respuesta con la esperanza de que los moderadores la atribuyan a Kenzic en lugar de a mí. – akaihola

Respuesta

0

¿Puede ser que usted puede anular el método get_context_data para agregar datos adicionales al contexto?

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 

y en su plantilla se puede obtener la lista de prensa y la lista artículo utilizando {{ press_list }} y {{ articles_list }}.

0

En mi opinión, una vista es simplemente una página. Una vista puede tener varias formas, que creo que es una mejor solución en su ejemplo.

Simplemente divide la plantilla en varios archivos, donde cada formulario tiene una plantilla pequeña, y usa la plantilla include directive para unirlos. Esto también tiene la ventaja adicional de que el formulario se puede reutilizar en otras vistas muy simple.

Su solución es básicamente como marcos pero en el servidor en lugar de en el navegador.

0

La forma más sencilla:

No utilice una visión genérica y el objeto paginator manualmente en tanto queryset.

No será tan largo, y no son algunas líneas las que van a matar a su IMO SECO.

La forma genérica, pero larga:

crear una vista que envolver los __init_ _ get_context y métodos para pasar argumentos a dos instancias de lista.

init debe instanciar ambos ListView, pasar los parámetros y agregar las instancias a los atributos de la envoltura.

get_context debe llamar al método de instancias getview de get_context y combinarlos en un objeto de contexto.

Asegúrese de configurar un template_object_name diferente para cada ListView para que no se anulen entre sí en el contexto dict.

hacer eso de una manera genérica, y no se olvide de que pusblish código en djangosnippet :-)

4

Kenzic fue capaz de lograr esto haciendo lo siguiente:

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,) 

    ] 
+5

Si no quiere ganar un representante como resultado de la respuesta de alguien, puede cambiarlo a CW. Además, han pasado dos meses y Kenzic no ha creado una respuesta; es razonable que otros intervengan y proporcionen una respuesta adecuada. – casperOne

Cuestiones relacionadas