64

这两段代码乍一看是相同的:

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_poll_list'
    queryset = Poll.active.order_by('-pub_date')[:5]

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

    def get_queryset(self):
        return Poll.active.order_by('-pub_date')[:5]

它们之间有什么区别吗?如果是:

什么方法更好?或者当设置queryset变量比覆盖get_queryset方法更好时?反之亦然。

4

5 回答 5

93

在您的示例中,覆盖querysetget_queryset具有相同的效果。我会稍微喜欢设置queryset,因为它不那么冗长。

当您设置时queryset,查询集仅在您启动服务器时创建一次。另一方面,get_queryset每个请求都会调用该方法。

这意味着get_queryset如果您想动态调整查询,这很有用。例如,您可以返回属于当前用户的对象:

class IndexView(generic.ListView):
    def get_queryset(self):
        """Returns Polls that belong to the current user"""
        return Poll.active.filter(user=self.request.user).order_by('-pub_date')[:5]

另一个get_queryset有用的示例是当您想要基于可调用项进行过滤时,例如,返回今天的民意调查:

class IndexView(generic.ListView):
    def get_queryset(self):
        """Returns Polls that were created today"""
        return Poll.active.filter(pub_date=date.today())

如果你试图通过设置来做同样的事情queryset,那么date.today()只会在视图加载时被调用一次,并且视图会在一段时间后显示不正确的结果。

class IndexView(generic.ListView):
    # don't do this!
    queryset = Poll.active.filter(pub_date=date.today())
于 2013-10-31T13:29:39.330 回答
14

queryset其他答案忽略了一个重要含义,即在流程开始时评估属性这一事实。因为你不只是创建一个查询集,你实际上是在对它进行切片,查询将在那个时候被评估。这意味着您此时只会获得前 5 名民意调查,即使您创建另一个民意调查,它们也不会刷新,直到流程重新启动。

这正是您应该使用get_queryset().

于 2013-10-31T17:41:43.473 回答
4

queryset 属性在内部使用,始终使用该方法(例如,您通常必须根据请求或会话变量执行自定义查询)

于 2013-10-31T13:28:09.537 回答
3

模型和查询集非常相似,但是如果提供查询集的值会覆盖模型的值。

模型是此视图显示的对象类型。

覆盖 get_queryset 控制此视图显示的特定实例(例如:最近创建的 5 个实例)

来自 Django 的文档:

模型:

此视图将为其显示数据的模型。指定model = Foo实际上与指定queryset = Foo.objects.all()相同,其中 objects 代表 Foo 的默认管理器。

查询集:

表示对象的 QuerySet。如果提供,则 queryset 的值将取代为 model 提供的值

获取查询集:

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

于 2017-10-21T14:10:46.637 回答
0

类内只包括

Class MyViewSet(GenericAPIView):

    queryset = ''

如果您不在任何地方使用查询集。

这对我有用。

谢谢

于 2018-04-27T06:42:33.000 回答