Django通用视图:何时使用ListView与DetailView

时间:2012-03-19 20:08:42

标签: python django django-views django-generic-views

我在博客应用程序中使用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

4 个答案:

答案 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以及简单的示例。