2012-09-05 27 views
6

Necesito hacer una paginación real en lugar de paginar en todos los datos recuperados. El ejemplo en el sitio de documentación de Django es como;Django Pagination

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}) 

Este código está paginating registros en todos los registros recuperados. Pero hay un problema. Tratar de recuperar todo el registro lleva mucho tiempo si hay tantos registros. Necesito una solución para recuperar los registros página por página desde la base de datos.

¿Hay alguna otra solución para hacer esto en Django?

+1

Esta pregunta ha sido contestada antes, ver aquí: http://stackoverflow.com/questions/10548744/django-lazy-queryset-and-pagination –

Respuesta

18

Realiza una suposición falsa. Django no recupera todos los objetos al paginar: corta apropiadamente el conjunto de preguntas, que usa LIMIT y COUNT en el SQL.

+0

¿Quiere decir ; La línea Contacts.objects.all() en el código se da en cuestión, ¿no recupera todo el registro? –

+4

Correcto. Los conjuntos de consulta son flojos, como lo explican los documentos, y no se realiza ninguna llamada de db hasta que se iteran o se cortan. –

+0

En realidad, debería mencionar que estoy usando MongoDB y la horquilla Mongo para modelar DJango. Probablemente esto sea para bases de datos SQL, no para Mongo fork. Porque lo probé, aún recupera todos los datos de db. Probablemente falta DJ Mongo para DJango. Pero gracias, no lo sabía. –

0

Mira dentro de la clase Paginator (django/core/paginator.py), solo busca las páginas requeridas. Solo hay un problema en las tablas grandes: si desea mostrar el número total de páginas, debe hacer que cuente (*) en toda la tabla, lo que puede llevar mucho tiempo en algunas bases de datos (es decir, postgresql, mysql con innodb).

Por cierto, intente utilizar vistas genéricas en django, ListView estaría bien aquí.

0

A QuerySet es un objeto perezoso. Cuando asigne contact_list = Contacts.objects.all(), Django NO golpeará la base de datos. Hasta que llame a los métodos como count(), filter(), first(), ... o contact_list[1:5], Django realmente recuperará los datos de la base de datos. Las sentencias de SQL que genere Django se correlacionarán con cada método y estas sentencias de SQL se enviarán a la base de datos.

E.g: contact_list[1:5] generan una instrucción SQL tienen LIMIT y OFFSET cláusulas.

En Paginator clase, el QuerySet habrá pasado a la su constructor

paginator = Paginator(contact_list, 25) 

Cuando se llama a paginator.page(page), la declaración se llama:

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