Foros del Web » Programando para Internet » Python »

Renderizar dos vistas en el mismo template

Estas en el tema de Renderizar dos vistas en el mismo template en el foro de Python en Foros del Web. Tengo dos vistas basadas en clase y me gustaría renderizar el resultado de ambas en la misma plantilla html Estas son las clases: @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); ...
  #1 (permalink)  
Antiguo 01/11/2014, 15:30
Avatar de kojicomics  
Fecha de Ingreso: junio-2013
Mensajes: 49
Antigüedad: 11 años, 6 meses
Puntos: 1
Renderizar dos vistas en el mismo template

Tengo dos vistas basadas en clase y me gustaría renderizar el resultado de ambas en la misma plantilla html

Estas son las clases:
Código Python:
Ver original
  1. class ListPosts(ListView):
  2.     '''Blogs posts'''
  3.     context_object_name = 'posts'
  4.     template_name = 'index/index.html'
  5.     paginate_by = 3
  6.  
  7.     def get_queryset(self):
  8.         lang_pk = Language.objects.filter(locale=self.request.LANGUAGE_CODE)
  9.         posts = Post.objects.filter(status='p')
  10.         posts_translated = PostTranslation.objects.filter(
  11.             post=posts,
  12.             language=lang_pk
  13.             )
  14.         return posts_translated
  15.  
  16.  
  17. class ListWorks(ListView):
  18.     '''Portfolio works'''
  19.     context_object_name = 'works'
  20.     template_name = 'index/index.html'
  21.     paginate_by = 3
  22.  
  23.     def get_queryset(self):
  24.         lang_pk = Language.objects.filter(locale=self.request.LANGUAGE_CODE)
  25.         works = Work.objects.filter(status='p')
  26.         works_translated = WorkTranslation.objects.filter(
  27.             work=works,
  28.             language=lang_pk
  29.             )
  30.         return works_translated

He probado a crear una tercera clase que retorne ambas querysets, pero no he logrado que funcione. Una de las formas que probé es esta:

Código Python:
Ver original
  1. class ListAll(TemplateView, ListPosts, ListWorks):
  2.     template_name = 'index/index.html'
  3.  
  4.     def get_context_data(self, **kwargs):
  5.         context = super(ListAll, self).get_context_data(**kwargs)
  6.         posts = ListPosts.get_queryset()
  7.         works = ListWorks.get_queryset()
  8.         if posts:
  9.             context['posts'] = posts
  10.         if works:
  11.             context['works'] = works
  12.         return context

En este caso, la aplicación me da el siguiente error:
Código:
'ListAll' object has no attribute 'object_list'
Mediante una única clase me funciona correctamente, pero me gustaría saber como hacerlo funcionar con clases independientes por simple curiosidad

De esta forma es como me funciona:
Código Python:
Ver original
  1. class ListAll(TemplateView):
  2.     template_name = 'index/index.html'
  3.  
  4.     def get_context_data(self, **kwargs):
  5.         context = super(ListAll, self).get_context_data(**kwargs)
  6.         lang_pk = Language.objects.filter(locale=self.request.LANGUAGE_CODE)
  7.         posts = Post.objects.filter(status='p')
  8.         works = Work.objects.filter(status='p')
  9.         context['posts'] = PostTranslation.objects.filter(
  10.             post=posts,
  11.             language=lang_pk
  12.             )[:3]
  13.         context['works'] = WorkTranslation.objects.filter(
  14.             work=works,
  15.             language=lang_pk
  16.             )[:3]
  17.         return context

Saludos
  #2 (permalink)  
Antiguo 16/11/2014, 18:24
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 9 meses
Puntos: 1360
Respuesta: Renderizar dos vistas en el mismo template

Tengo varias preguntas:

1. ¿Como te encargarías de la paginación de 2 modelos al mismo tiempo? (Que lo puedes resolver fácilmente usando prefijos o algo por el estilo).

2. ¿Que sentido tiene? Realmente no he encontrado una sola pagina o escenario donde paginar 2 cosas tenga sentido. O remotamente agradable para el usuario.

3. Creo que necesitas un diagrama de flujo de cuando usar vistas genéricas, porque este parece ser un caso para una vista basa en funciones. (No es una pregunta).
  #3 (permalink)  
Antiguo 17/11/2014, 07:46
Avatar de kojicomics  
Fecha de Ingreso: junio-2013
Mensajes: 49
Antigüedad: 11 años, 6 meses
Puntos: 1
Respuesta: Renderizar dos vistas en el mismo template

Mi aplicación consiste en un blog y un portfolio, por lo tanto decidí mostrar los tres últimos posts y los tres últimos trabajos en el home del sitio web a modo de resumen

Ésto lo he resuelto perfectamente con el último fragmento de código que puse en la pregunta, básicamente un TemplateView que devuelve el valor de ambas consultas en una lista

Mi duda es simplemente una curiosidad de cómo poder devolver este mismo resultado mediante 2 clases ListView independientes, pero después de reflexionar sobre tus preguntas me he dado cuenta de que no tiene sentido

Gracias
  #4 (permalink)  
Antiguo 17/11/2014, 22:34
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 9 meses
Puntos: 1360
Respuesta: Renderizar dos vistas en el mismo template

Exacto, no tienen sentido por que lo que tratas de hacer no tiene sentido.

Tu panorama es limitado, tienes 2 vistas, donde su responsabilidad es listar los temas, siguiendo algún criterio, y con paginación, con su propio template, etc...

Mientras que lo que tratas en tu segunda vista es mostrar n1, n2, ..., nm elementos de m modelos. Sin paginación, con un criterio particular para cada modelo. Que es algo completamente diferente. Mas aun, probablemente vayas a definir un template completamente diferente.

Sinceramente, no le veo problema a hacer:
Código Python:
Ver original
  1. from django.shortcuts import render
  2.  
  3. def home(request):
  4.     template_name = 'myapp/index.html'
  5.     # Protip: Crea un ModelManager para evitar esta linea larga
  6.     data = {}
  7.     data['post_list'] = PostTranslation.objects.filter(post__status='p', language__locale=request.LANGUAGE_CODE)[:3]
  8.     data['work_list'] = WorkTranslation.objects.filter(work__status='p', language__locale=request.LANGUAGE_CODE)[:3]
  9.     return render(request, template_name, data)

Es mas compacto, mas directo y conciso, sin toda esa herencia, que no sabes como funciona a menos que leas el código.

Etiquetas: django
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:20.