在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]
这样的事情(就像类属性一样)吗?
答案 0 :(得分:2)
这里有一个完整的答案,基于文档阅读,测试,答案在这里(感谢Daniel Roseman和knbk,以及半猜测(所以请告诉我是否错了)。
通用视图确实需要知道要执行的模型。这是因为通用视图必须在后台执行查询以检索所需的对象(视图类型之间会有所不同,ListView
,DetailView
等)。
因此,当调用方法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)
因为我们不会覆盖get_queryset,所以我们不需要它,因为我们直接在那里指定查询。
不,因为[:5]会导致对查询集进行评估。如果我们将它放在模型定义中,那么对视图的所有请求都将使用相同的5个项目:即使添加了新的民意调查,它们也不会出现在已经评估的列表中(直到服务器重新启动或进程终止)