首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Django:分页的ListView数据库性能

Django:分页的ListView数据库性能
EN

Stack Overflow用户
提问于 2013-10-12 10:21:46
回答 4查看 2.2K关注 0票数 4

我有一个带有分页的ListView

代码语言:javascript
运行
复制
class StoriesListView(ListView):
    model = Story
    paginate_by = 20

    def get_queryset(self):
        return Story.objects.all().order_by('-updated_at')

我在数据库中有1000个Story对象。当用户加载我的视图时会发生什么?是从数据库中查询所有的1000条,还是只查询20条?我怎么才能优化这个?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-10-12 10:36:23

这取决于你如何使用它。QuerySet对象是懒惰,在这种情况下,SQL查询将添加LIMITOFFSET,因此查询总是只返回20个结果。但是,当您想在模板中使用相关对象时,您必须使用select_relatedprefetch_related方法优化查询(否则,您将得到来自主查询的每个记录的附加查询)。

我认为您应该阅读如何在django框架中使用优化数据库访问

希望这能有所帮助。

票数 6
EN

Stack Overflow用户

发布于 2013-10-12 10:37:05

Paginator类接受get_queryset的返回值(在本例中为整个查询集),并将其连接起来,使您只访问20个查询集。它需要对整个查询集进行操作,否则您将无法使用它来显示页面列表。

您可以看到,按照代码来查看它的运行情况:

得到() > 数据() > queryset() > Paginator.init()

这意味着在模板上下文中queryset变量是整个查询集。page变量仅用于获取属于当前页的对象。这是由拼接初始查询集完成的,它将对其进行评估并命中DB。您可以遍历页面中的对象:{% for object in page %},这样就不会再次访问数据库了:

代码语言:javascript
运行
复制
# https://github.com/django/django/blob/master/django/core/paginator.py#L119
def __getitem__(self, index):
    if not isinstance(index, (slice,) + six.integer_types):
        raise TypeError
    # The object_list is converted to a list so that if it was a QuerySet
    # it won't be a database hit per __getitem__.
    if not isinstance(self.object_list, list):
        self.object_list = list(self.object_list)
    return self.object_list[index]
票数 3
EN

Stack Overflow用户

发布于 2013-10-12 10:34:48

它只会得到20个物体。分页器将get_queryset方法的结果作为开始查询集,并且只有在迭代时才会访问数据库,所以您很好。get_queryset方法不访问数据库本身。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19333102

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档