Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Pagination

I need to make real pagination instead of paginating on all retreived data. The example in Django documentation site, is like;

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

This code is paginating records on all retreived records. But there is a trouble. Trying to retreive all record takes many time if there are so many records. I need a solution to retrieve the records page by page from database.

Is there another solution to do this in Django?

like image 789
Ahmet DAL Avatar asked Sep 05 '12 06:09

Ahmet DAL


People also ask

How does pagination work in Django REST framework?

Pagination is only performed automatically if you're using the generic views or viewsets. If you're using a regular APIView , you'll need to call into the pagination API yourself to ensure you return a paginated response. See the source code for the mixins. ListModelMixin and generics.

What is Django paginator?

Django provides a few classes that help you manage paginated data – that is, data that's split across several pages, with “Previous/Next” links. These classes live in django/core/paginator.py. For examples, see the Pagination topic guide.


2 Answers

You make a false assumption. Django does not retrieve all objects when paginating: it slices the queryset appropriately, which uses LIMIT and COUNT on the SQL.

like image 170
Daniel Roseman Avatar answered Oct 11 '22 18:10

Daniel Roseman


A QuerySet is a lazy object. When you assign contact_list = Contacts.objects.all(), Django will NOT hit the database. Until you call the methods such as count(), filter(), first(),..., or contact_list[1:5], Django will really retrieve data from the database. SQL statements that Django generate will correlate to each method and these SQL statments will be sent to the DB.

E.g: contact_list[1:5] generate a SQL statement have LIMIT and OFFSET clauses.

In Paginator class, the QuerySet will passed to the its constructor

paginator = Paginator(contact_list, 25)

When you call paginator.page(page), the statement is called:

return self._get_page(self.object_list[bottom:top], number, self)
like image 1
Hùng Ng Vi Avatar answered Oct 11 '22 18:10

Hùng Ng Vi