2012-09-05 13 views
6

Ho bisogno di fare una paginazione reale invece di impaginare su tutti i dati recuperati. L'esempio nel sito di documentazione di Django è simile;Paginazione 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}) 

Questo codice è impaginare record su tutti i record retreived. Ma c'è un problema. Cercare di recuperare tutto il record richiede molto tempo se ci sono così tanti record. Ho bisogno di una soluzione per recuperare i record pagina per pagina dal database.

C'è un'altra soluzione per farlo in Django?

+1

Questa domanda è stato risposto in precedenza, vedi qui: http://stackoverflow.com/questions/10548744/django-lazy-queryset-and-pagination –

risposta

18

Si fa una falsa ipotesi. Django non recupera tutti gli oggetti durante la impaginazione: taglia in modo appropriato il queryset, che utilizza LIMIT e COUNT sull'SQL.

+0

Intendi ; La riga Contacts.objects.all() nel codice è indicata in questione, non recupera tutto il record? –

+4

corretto. I set di query sono pigri, come spiegano i documenti, e nessuna chiamata db viene effettuata finché non vengono iterati o tagliati. –

+0

In realtà dovrei menzionare che sto usando MongoDB e la forcella Mongo per la modellazione di DJango. Probabilmente questo è per i database SQL, non per la forcella Mongo. Perché l'ho provato, recupera ancora tutti i dati da db. Probabilmente è la mancanza della forcella Mongo per DJango. Ma grazie non lo sapevo. –

0

Cerca all'interno della classe Paginator (django/core/paginator.py), recupera solo le pagine richieste. C'è solo un problema sulle grandi tabelle: se vuoi mostrare i numeri di pagina totali devi fare il conteggio (*) sull'intera tabella che può impiegare molto tempo in alcuni database (ad esempio postgresql, mysql con innodb).

BTW, prova ad utilizzare viste generiche in django, ListView andrebbe bene qui.

0

A QuerySet è un oggetto pigro. Quando assegni contact_list = Contacts.objects.all(), Django NON colpirà il database. Finché non chiami metodi come count(), filter(), first(), ... o contact_list[1:5], Django recupererà davvero i dati dal database. Le istruzioni SQL generate da Django saranno correlate a ciascun metodo e queste statistiche SQL verranno inviate al DB.

E.g: contact_list[1:5] generare una dichiarazione SQL avere clausole LIMIT e OFFSET.

In Paginator classe, sarà passato al suo costruttore

paginator = Paginator(contact_list, 25) 

Quando si chiama paginator.page(page) il QuerySet, la dichiarazione si chiama:

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