Django分页

时间:2012-09-05 06:48:54

标签: python django mongodb django-pagination

我需要进行真正的分页,而不是对所有已检索的数据进行分页。 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 个答案:

答案 0 :(得分:18)

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

例如: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)

答案 3 :(得分: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})