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_object
和 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']
使用 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_object
和 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']