使用get_queryset()方法或设置queryset变量?

时间:2013-10-31 13:01:39

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

这两段代码在第一时间是相同的:

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方法?反之亦然。

5 个答案:

答案 0 :(得分:64)

在您的示例中,覆盖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())

答案 1 :(得分:7)

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

这正是您应该使用get_queryset()

的时候

答案 2 :(得分:4)

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

答案 3 :(得分:2)

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

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

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

来自Django的文档:

模型:

  

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

查询集:

  

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

get_queryset:

  

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

答案 4 :(得分:0)

内部课程只包括

.row {
    height: calc(70vh - 60px);
}

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

这对我有用。

由于