9

我需要进行真正的分页,而不是对所有检索到的数据进行分页。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 中有另一种解决方案吗?

4

4 回答 4

21

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

于 2012-09-05T07:03:53.287 回答
0

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

顺便说一句,尝试在 django 中使用通用视图,ListView在这里会很好。

于 2012-09-05T07:02:35.860 回答
0

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

eg:contact_list[1:5]生成一个SQL语句有LIMITOFFSET子句。

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

paginator = Paginator(contact_list, 25)

当您调用 时paginator.page(page),将调用该语句:

return self._get_page(self.object_list[bottom:top], number, self)
于 2017-03-28T05:25:50.153 回答
0

在这里,我们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})
于 2020-08-23T03:45:51.363 回答