django中queryset属性和get_queryset()方法的区别?

8e2ybdfx  于 2023-10-21  发布在  Go
关注(0)|答案(1)|浏览(122)

我正在学习Django中基于类的视图。我在阅读Django文档,了解了queryset属性和get_queryset()方法。当谷歌他们我遇到了这个answer
我试着用我的代码复制结果:

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

    def get_queryset(self):
        return Question.objects.order_by('-pub_date')[:2]

class IndexView2(generic.ListView):
    template_name = 'polls/index2.html'
    context_object_name = 'latest_question_list2'
    queryset = Question.objects.all()

在回答中提到,当你设置查询集时,查询集只在你启动服务器时创建一次。另一方面,每次请求都会调用get_queryset方法。
但我能够在数据库中插入问题,它们在页面index2.html中可用,而无需重新启动,我能够更改数据库,刷新页面后,更改会反映在页面index2.html上。
我在Google上搜索了一下,找到了这个link。在DRF网站中,提到了queryset将被评估一次,并且这些结果将被缓存用于所有后续请求。
你能指出我哪里走错了吗?我错过了什么环节?

bbmckpt7

bbmckpt71#

QuerySet只计算一次,但get_queryset的默认实现将使用queryset.all(),因此每次都构造一个新的查询集,强制重新计算。
实际上,**.get_queryset(…)**方法[GitHub]的实现可以使用:

def get_queryset(self):
    if self.queryset is not None:
        queryset = self.queryset
        if isinstance(queryset, QuerySet):
            queryset = queryset.all()
    elif self.model is not None:
        queryset = self.model._default_manager.all()
    else:
        raise ImproperlyConfigured(
            "%(cls)s is missing a QuerySet. Define "
            "%(cls)s.model, %(cls)s.queryset, or override "
            "%(cls)s.get_queryset()." % {
                'cls': self.__class__.__name__
            }
        )
    ordering = self.get_ordering()
    if ordering:
        if isinstance(ordering, str):
            ordering = (ordering,)
        queryset = queryset.order_by(*ordering)

    return queryset

因此,这意味着我们每次都要制作一个新的QuerySet的“副本”来进行评估。如果没有指定queryset,它将查找model属性,并使用该模型的_default_manager
如果你指定了一个ordering属性,那么这意味着它也会对查询集进行排序。

相关问题