【问题标题】:Django PaginationDjango分页
【发布时间】:2012-08-29 20:20:30
【问题描述】:

我需要进行真正的分页,而不是对所有检索到的数据进行分页。 Django 文档站点中的示例是这样的;

def listing(request):
    contact_list = Contacts.objects.all()
    paginator = Paginator(contact_list, 25) # Show 25 contacts per page

    page = request.GET.get('page')
    try:
        contacts = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        contacts = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        contacts = paginator.page(paginator.num_pages)

    return render_to_response('list.html', {"contacts": contacts})

此代码正在对所有检索到的记录进行分页。但是有一个麻烦。如果有这么多记录,尝试检索所有记录需要很长时间。我需要一个解决方案来从数据库中逐页检索记录。

在 Django 中有其他解决方案吗?

【问题讨论】:

标签: python django mongodb django-pagination


【解决方案1】:

你做了一个错误的假设。分页时 Django 不会检索所有对象:它对查询集进行适当的切片,在 SQL 上使用 LIMIT 和 COUNT。

【讨论】:

  • 你的意思是;代码中的contacts.objects.all()行有问题,不检索所有记录?
  • 正确。正如文档所解释的那样,查询集是惰性的,并且在迭代或切片之前不会进行 db 调用。
  • 实际上我应该提到我正在使用 MongoDB 和 Mongo fork 进行 DJango 建模。可能这适用于 SQL 数据库,而不是 Mongo fork。因为我试过了,它仍然从数据库中检索所有数据。 DJango 可能缺少 Mongo fork。不过谢谢你,我不知道。
【解决方案2】:

查看 Paginator 类 (django/core/paginator.py),它只获取需要的页面。大表只有一个问题:如果要显示总页码,则必须对整个表进行 count(*),这在某些数据库(例如 postgresql、mysql 和 innodb)中可能需要很长时间。

顺便说一句,尝试在 django 中使用通用视图,ListView 在这里就可以了。

【讨论】:

    【解决方案3】:

    QuerySet 是一个惰性对象。当您分配contact_list = Contacts.objects.all() 时,Django 将不会访问数据库。直到调用count()filter()first()、...、contact_list[1:5] 等方法,Django 才会真正从数据库中检索数据。 Django 生成的 SQL 语句将与每个方法相关联,这些 SQL 语句将被发送到数据库。

    例如:contact_list[1:5] 生成具有LIMITOFFSET 子句的SQL 语句。

    Paginator 类中,QuerySet 将传递给其构造函数

    paginator = Paginator(contact_list, 25)
    

    当你调用paginator.page(page)时,语句被调用:

    return self._get_page(self.object_list[bottom:top], number, self)
    

    【讨论】:

      【解决方案4】:

      这里我们使用get_page() 获取页面数据(1 页包含 25 个数据)。我建议这样:

      def listing(request):
          contact_list = Contacts.objects.all()
          paginator = Paginator(contact_list, 25) # Show 25 contacts per page
          page = request.GET.get('page')
          contacts = paginator.get_page(page)
      
          return render_to_response('list.html', {"contacts": contacts})
      

      【讨论】:

        猜你喜欢
        • 2021-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-11
        • 1970-01-01
        • 1970-01-01
        • 2022-10-05
        • 1970-01-01
        相关资源
        最近更新 更多