【问题标题】:Difference between queryset attribute and get_queryset() method in django?django中queryset属性和get_queryset()方法的区别?
【发布时间】:2021-06-24 19:33:28
【问题描述】:

我正在 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 上。

我进一步搜索并找到了这个link。在 DRF 网站中,提到查询集将被评估一次,这些结果将被缓存以供所有后续请求使用。

你能指出我哪里出错了吗?我缺少什么链接?

【问题讨论】:

标签: python django django-class-based-views


【解决方案1】:

QuerySet 被评估一次,但get_queryset 的默认实现将使用queryset.all(),因此每次都会构造一个新的查询集来强制重新评估。

确实,implementation of the .get_queryset(…) method [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 属性,则意味着它也会对查询集进行排序。

【讨论】:

    猜你喜欢
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    • 2017-05-02
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多