2012-09-05 43 views
6

我需要制作真正的分页,而不是分页所有的retreived数据。 Django文档站点中的示例如下所示;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中做到这一点?

+1

这个问题已经回答过了,在这里看到: http://stackoverflow.com/questions/10548744/django-lazy-queryset-and-pagination –

回答

18

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

+0

你的意思是;代码中的Contacts.objects.all()行有问题,不检索所有记录? –

+4

正确。查询集是懒惰的,正如文档解释的一样,并且不会调用db调用,直到它们被迭代或切片。 –

+0

实际上,我应该提到我正在使用MongoDB和Mongo fork进行DJango建模。可能这是针对SQL数据库的,而不是Mongo fork。因为我试过了,它仍然从数据库中获取所有数据。 DJango可能缺乏Mongo fork。但是,谢谢你,我不知道。 –

0

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

顺便说一句,尝试在django中使用通用视图,ListView将在这里罚款。

0

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

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