Django教程:什么是get_queryset以及为什么" model = poll"不需要吗?

时间:2014-05-29 14:51:22

标签: python django

在Django官方教程中,介绍了“通用视图”。

我们有:

(...)
    class IndexView(generic.ListView):
        template_name = 'polls/index.html'
        context_object_name = 'latest_poll_list'

        def get_queryset(self):
            """Return the last five published polls."""
            return Poll.objects.order_by('-pub_date')[:5]


    class DetailView(generic.DetailView):
        model = Poll
        template_name = 'polls/detail.html'
(...)

(网址:https://docs.djangoproject.com/en/1.6/intro/tutorial04/#amend-views

它说:

  

每个通用视图都需要知道它将采用什么模型。   这是使用model属性提供的。

1 /那么为什么我们不像在DetailView类中那样在IndexView类中使用model = poll

2 /第二个 - 也许是相关的 - 问题是:什么是def get_queryset(),为什么我们需要它?我们不能只做像queryset = Poll.objects.order_by('-pub_date')[:5]这样的事情(就像类属性一样)吗?

2 个答案:

答案 0 :(得分:2)

这里有一个完整的答案,基于文档阅读,测试,答案在这里(感谢Daniel Roseman和knbk,以及半猜测(所以请告诉我是否错了)。

通用视图确实需要知道要执行的模型。这是因为通用视图必须在后台执行查询以检索所需的对象(视图类型之间会有所不同,ListViewDetailView等)。 因此,当调用方法as_view()时,首先调用get_queryset()并返回queryset属性的值。如果未设置后者,则调用模型对象管理器(all())的poll.objects方法。

注意:虽然ListView get_queryset() isn'nt very clear的文档是DetailView seems to confirm the above behavior的文档:

  

返回将用于检索其对象的查询集   此视图将显示。默认情况下,get_queryset()返回值   如果设置了queryset属性,否则它构造一个   通过在模型属性的默认值上调用all()方法来实现QuerySet   管理器。

除非它说我认为all()时会调用objects.get(pk=)方法,因为它是" DetailView"而不是ListView

最后,正如knbk所提到的(并在文档中确认),在没有步骤参数的切片时不会对查询集进行求值,这意味着在问题的示例中(=在Django官方教程中),放置{ {1}}可以正常工作(django 1.6测试)。

答案 1 :(得分:-1)

  1. 因为我们不会覆盖get_queryset,所以我们不需要它,因为我们直接在那里指定查询。

  2. 不,因为[:5]会导致对查询集进行评估。如果我们将它放在模型定义中,那么对视图的所有请求都将使用相同的5个项目:即使添加了新的民意调查,它们也不会出现在已经评估的列表中(直到服务器重新启动或进程终止)