在Django官方教程中,介绍了“通用 View ”。
我们有:
(...)
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)
它说:
Each generic view needs to know what model it will be acting upon. This is provided using the model attribute.
1/那为什么我们不像在 DetailView 类中那样在 IndexView 类中使用 model = poll
呢?
2/第二个可能相关的问题是:什么是 def get_queryset()
以及我们为什么需要它?难道我们不能做像 queryset = Poll.objects.order_by('-pub_date')[:5]
这样的事情(就像类属性一样)吗?
最佳答案
这是一个完整的答案,基于文档阅读、测试、此处的答案(感谢 Daniel Roseman 和 knbk,以及一半的猜测(如果我错了请告诉我)。
通用 View 确实需要知道在哪个模型上执行。这是因为通用 View 必须在后台执行查询以检索所需的对象(这将因 View 类型、ListView
、DetailView
等而异)。
所以当方法as_view()
被调用时,首先调用get_queryset()
并返回queryset
属性的值。如果未设置后者,则调用模型对象管理器 (poll.objects
) 的 all()
方法。
注意:ListView
的 get_queryset()
的文档 isn'nt very clear , DetailView
的 seems to confirm the above behavior :
Returns the queryset that will be used to retrieve the object that this view will display. By default, get_queryset() returns the value of the queryset attribute if it is set, otherwise it constructs a QuerySet by calling the all() method on the model attribute’s default manager.
除非它说 all()
方法会在我认为 objects.get(pk=)
会被调用时调用,因为它是“DetailView
"而不是 ListView
。
最后,正如 knbk 提到的(并在文档中确认),在没有步骤参数的情况下切片时不会评估查询集,这意味着在问题的示例中(= 在 Django 官方教程中),将 queryset = Poll. objects.order_by('-pub_date')[:5]
也可以正常工作(django 1.6 测试)。
关于python - Django 教程 : What is get_queryset and why "model = poll" isn't needed?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23936228/