我在博客应用程序中使用Django基于类的通用视图。我的一个视图显示了具有特定标记的帖子列表。我可以将此视图编写为ListView
个帖子,按标记过滤。或者我可以将此视图编写为标记的DetailView
,并将相关帖子添加到上下文中。
一种方式比其他方式更合适 - 或Pythonic?
ListView
方法似乎更具语义性,因为我想要的是帖子的列表,但它也稍微复杂一些。它要求我覆盖两种方法。 DetailView
方法只需要我覆盖一种方法。
class PostTagView(ListView):
"""Display all blog posts with a given tag."""
queryset = Post.objects.published()
def get_context_data(self, **kwargs):
context = super(PostTagView, self).get_context_data(**kwargs)
context['tag'] = get_object_or_404(Tag, slug=self.kwargs['slug'])
return context
def get_queryset(self, **kwargs):
queryset = super(PostTagView, self).get_queryset()
return queryset.filter(tags__slug=self.kwargs['slug'])
class TagDetailView(DetailView):
"""Display all blog posts with a given tag."""
model = Tag
def get_context_data(self, **kwargs):
context = super(TagDetailView, self).get_context_data(**kwargs)
context['object_list'] = Post.objects.published().filter(tags__slug=self.kwargs['slug'])
return context
答案 0 :(得分:9)
根据经验,请查看URL中的参数。如果您使用slug
Tag
,那么您最有可能处理DetailView
而不是ListView
。
在这种情况下,第二种方法使用更少的代码,它更优雅。但是,它还取决于您稍后要对视图执行的操作。如果您要添加表单来编辑帖子,则可能需要使用ListView
。但是没有技术上的理由偏爱另一个,只是你最终可能会在一种方法中编写更多的代码而不是另一种方法。
答案 1 :(得分:1)
有趣的问题。不幸的是,答案并不那么有趣:无论哪种对您和您的应用最有意义。对于任何一种方法,都可以平等地争论,所以它实际上只是一种判断。
答案 2 :(得分:1)
ListView和DetailView在技术上都不相同, 例如,您无法在urls.py中提供如下所示的DetailView的路径,
path('schools_detail/',views.SchoolDetailView.as_view(),name = "detail"),
这将产生以下错误,
通用详细信息视图SchoolDetailView必须使用 对象pk或URLconf中的子弹。
这意味着,如果我们有一个名为Student的表和另一个名为School的表,则可以使用ListView列出如下所示的所有学校,
path('list/',views.SchoolListView.as_view(),name = "list"),
如果我们想在单击学校图标时列出各个学校的学校详细信息,则可以使用Django在内部创建的学校的主键,并以url模式捕获它(在我的情况下为url模式)将会是“ list / {{school.id}}”,因此要捕获此信息,我们必须为DetailsView提供如下路径,
path('list/<int:pk>/',views.SchoolDetailView.as_view(),name = "detail"),
因此,最重要的是,在大多数情况下,您可以将ListView用作普通视图,如果您要访问另一个View,但仅访问该视图中具有主键的特定详细信息,则可以使用DetailsView( DetailsView的url模式将通过在url中提供主键信息来生成,而在url中没有主键将无法使用,因为它将不会获取所有信息,而只会获取与url中的主键相关的信息。
答案 3 :(得分:0)
基于类的通用视图的用例在文章中得到了完美的描述:
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Generic_views
在上述文章中,您将知道何时/为什么以及如何使用ListView / DetailView以及简单的示例。