Django:一次 url 搜索两种模型 (cbv)

Django: one url search in two models (cbv)

使用 Django,我正在寻找一种方法来使用一个 url 模式(带有 slug)来查询一个模型,如果没有找到则查询第二个模型。我正在使用 Class 基于视图。

我正在关注这个answer,正在调用下一个视图。但随后出现以下错误:

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

我不知道如何将 slug 传递给下一个视图。

我的url:

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

我的 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'

问题是您正在弹出 slug,这会将它从 kwargs 中删除。这意味着 slug 没有传递给视图。

您可以将其更改为:

post_or_page_slug = kwargs.pop['slug'] 

我通常不鼓励在另一个视图中调用 MyView.as_view(request, *args, **kwargs)。 Class 基于视图的目的是通过子类化来扩展,而不是通过在其他视图中调用它们。

对于您示例中的两个视图,您可以通过覆盖 get_objectget_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']