2012-09-05 10 views
6

Potrzebuję zrobić prawdziwą paginację zamiast stronicowania na wszystkich odzyskanych danych. Przykład w witrynie dokumentacji Django jest podobny;Pagina 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}) 

Ten kod jest Stronicowanie zapisy dotyczące wszystkich retreived rekordów. Ale jest problem. Próba odzyskania całego rekordu zajmuje wiele czasu, jeśli jest tak wiele rekordów. Potrzebuję rozwiązania, aby pobrać stronę rekordów po stronie z bazy danych.

Czy jest inne rozwiązanie, aby to zrobić w Django?

+1

To pytanie zostało odebrane przed, zobacz tutaj: http://stackoverflow.com/questions/10548744/django-lazy-queryset-and-pagination –

Odpowiedz

18

Dokonujesz fałszywego założenia. Django nie pobiera wszystkich obiektów podczas stronicowania: wycina kwerendę odpowiednio, używając LIMIT i COUNT w SQL.

+0

Masz na myśli ; W pytaniu podana jest linia Contacts.objects.all(), która nie pobiera wszystkich rekordów? –

+4

Prawidłowe. Zestawy zapytań są leniwy, jak wyjaśniają dokumenty, i nie ma wywołania db, dopóki nie zostaną powtórzone lub pocięte na plasterki. –

+0

Właściwie powinienem wspomnieć, że używam MongoDB i widelca Mongo do modelowania DJango. Prawdopodobnie jest to dla baz danych SQL, a nie dla Mongo fork. Ponieważ go wypróbowałem, nadal odzyskuje wszystkie dane z db. Prawdopodobnie brak widelca Mongo dla DJango. Ale dziękuję, nie wiedziałem o tym. –

0

Zajrzyj do klasy Paginator (django/core/paginator.py), pobiera tylko wymagane strony. W przypadku dużych tabel występuje tylko jeden problem: jeśli chcesz wyświetlić całkowite liczby stron, musisz liczyć (*) na całej tabeli, co może zająć dużo czasu w niektórych bazach danych (np. Postgresql, mysql with innodb).

BTW, spróbuj użyć ogólnych widoków w django, ListView byłoby w porządku tutaj.

0

A QuerySet to obiekt leniwy. Po przypisaniu contact_list = Contacts.objects.all(), Django NIE trafi w bazę danych. Dopóki nie wywołasz takich metod, jak count(), filter(), first(), ... lub contact_list[1:5], Django naprawdę pobierze dane z bazy danych. Instrukcje SQL generowane przez Django będą korelować z każdą metodą, a te instrukcje SQL zostaną przesłane do bazy danych.

E.g: contact_list[1:5] generowanie instrukcji SQL ma klauzule LIMIT i OFFSET.

W Paginator klasie, QuerySet zostanie przekazany do konstruktora

paginator = Paginator(contact_list, 25) 

Po wywołaniu paginator.page(page), zestawienie nazywa się:

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