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?
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.
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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With