Usando Django, estoy buscando una manera de usar un patrón de URL (con slug) para consultar un modelo y, si no se encuentra nada, consultar un segundo modelo. Estoy usando vistas basadas en clases.
Estoy siguiendo esta respuesta y se está llamando a la siguiente Vista. Pero luego me sale el siguiente error:
"La vista de detalles genérica debe llamarse con un objeto pk o un slug".
No sé cómo pasar el slug a la siguiente vista.
Mi URL:
url(r'^(?P<slug>[-\w]+)/$', SingleView.as_view(), name='singleview'),Mis CBV:
class SingleView(DetailView): def dispatch(self, request, *args, **kwargs): post_or_page_slug = kwargs.pop('slug') if Page.objects.filter(slug=post_or_page_slug).count() != 0: return PageDetailView.as_view()(request, *args, **kwargs) elif Post.objects.filter(slug=post_or_page_slug).count() != 0: return PostDetailView.as_view()(request, *args, **kwargs) else: raise Http404 class PageDetailView(DetailView): model = Page template_name = 'page-detail.html' class PostDetailView(DetailView): model = Post template_name = 'post-detail.html'El problema es que estás reventando la babosa, lo que la elimina de los kwargs. Esto significa que el slug no se pasa a la vista.
Puedes cambiarlo a:
post_or_page_slug = kwargs.pop['slug'] Por lo general, desaconsejaría llamar a MyView.as_view(request, *args, **kwargs) dentro de otra vista. Las vistas basadas en clases están destinadas a extenderse mediante subclases, no llamándolas dentro de otras vistas.
Para las dos vistas de su ejemplo, puede combinarlas en una sola vista anulando get_object y get_template_names .
from django.http import Http404 class PageOrPostDetailView(DetailView): def get_object(self): for Model in [Page, Post]: try: object = Model.objects.get(slug=self.kwargs['slug']) return object except Model.DoesNotExist: pass raise Http404 def get_template_names(self): if isinstance(self.object, Page): return ['page-detail.html'] else: return ['post-detail.html']