Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

202
Views
Django: one url search in two models (cbv)

Using Django, I'm looking for a way to use one url patern (with slug) to query one model and if nothing is found query a second model. I'm using Class Based Views.

I am following this answer, and the next View is being called. But then I get the following error:

"Generic detail view must be called with either an object pk or a slug."

I can't figure out how to pass the slug to the next View.

My url:

url(r'^(?P<slug>[-\w]+)/$', SingleView.as_view(), name='singleview'),

My CBV's:

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'
over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

The problem is that you are popping the slug, which removes it from kwargs. This means that the slug is not getting passed to the view.

You can change it to:

post_or_page_slug = kwargs.pop['slug'] 

I would usually discourage calling MyView.as_view(request, *args, **kwargs) inside another view. Class based views are intended to be extended by subclassing, not by calling them inside other views.

For the two views in your example, you could combine them into a single view by overriding get_object and 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']
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!