Pagination - potatoscript/django GitHub Wiki
📚 Pagination – Breaking Big Lists into Pages
When your application has large datasets, returning all the data at once can overwhelm both your server and users. Pagination allows you to break up a large list of items into smaller, more manageable chunks, or pages. This is a critical feature in any web application, especially when you’re working with a list of items that might grow into the thousands.
In this tutorial, we’ll explore how to implement pagination in your Django REST API using Django REST Framework (DRF).
🧩 Step 1: Why Pagination is Important
Imagine you have an API that returns a list of 1000 books from a database. If you were to request all those books at once, the response could be too large, slow to load, and might even cause performance issues.
Pagination helps by:
- Reducing load time for users.
- Optimizing server performance, as it only sends a portion of the data.
- Improving user experience by allowing users to easily navigate between different chunks of data.
🧩 Step 2: How to Enable Pagination in DRF
Django REST Framework comes with several ways to paginate your API responses. We'll cover simple pagination and page size settings.
🛠️ Step 2.1: Enable Pagination Globally
To enable pagination in Django REST Framework, you need to configure the pagination settings in the settings.py
file of your Django project.
- Open your
settings.py
file. - Add the following pagination settings to the
REST_FRAMEWORK
dictionary:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10, # This is the number of items per page
}
Explanation:
- DEFAULT_PAGINATION_CLASS: Specifies the pagination style.
PageNumberPagination
is one of the available options, which allows clients to request specific pages. - PAGE_SIZE: Specifies the number of items per page. Here, we've set it to 10, but you can adjust it based on your needs.
This setting will apply pagination to all of your API views that return large datasets.
🧩 Step 3: Customizing Pagination
If you want more control over how your pagination works, Django REST Framework allows you to create custom pagination classes. This can be useful if you need to customize things like the page size or the pagination style.
🛠️ Step 3.1: Custom Pagination Class
You can create a custom pagination class by subclassing one of DRF's built-in pagination classes. For instance, you might want to change how the response is formatted or adjust how the pages are numbered.
Here's an example of a custom pagination class:
# pagination.py
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
class CustomPagination(PageNumberPagination):
page_size = 5 # Items per page
page_size_query_param = 'page_size' # Allow clients to pass a custom page size
max_page_size = 100 # Limit the maximum number of items per page
def get_paginated_response(self, data):
return Response({
'count': self.page.paginator.count,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'results': data,
})
Explanation:
- page_size: Set the default number of items per page.
- page_size_query_param: Allow the client to change the page size by passing a query parameter like
?page_size=20
. - max_page_size: Limit the maximum number of items returned per page (even if the client requests a larger page size).
- get_paginated_response: Customize how the paginated response is returned.
Now, let’s tell DRF to use this custom pagination class in your settings.py
file:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'myapp.pagination.CustomPagination', # Custom pagination class
'PAGE_SIZE': 10,
}
🧩 Step 4: Adding Pagination to Your Views
Once pagination is enabled, you need to ensure your API views are set up to handle it. DRF handles this automatically for most cases, but let’s see how it works with your Book API from the previous examples.
🛠️ Step 4.1: Apply Pagination to a View
Assuming you have a list view for your Book model, you can simply use pagination by modifying the view:
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from .models import Book
from .serializers import BookSerializer
class BookList(APIView):
def get(self, request):
books = Book.objects.all() # Retrieve all books
paginator = PageNumberPagination() # Create a paginator instance
result_page = paginator.paginate_queryset(books, request) # Paginate the queryset
serializer = BookSerializer(result_page, many=True) # Serialize the paginated data
return paginator.get_paginated_response(serializer.data) # Return paginated response
In this view:
- The
PageNumberPagination()
object automatically handles pagination of thebooks
queryset. - The
paginate_queryset()
method paginates the data based on the page number provided by the client. - The
get_paginated_response()
method formats the response to include pagination metadata like thecount
,next
, andprevious
links.
🧩 Step 5: Testing Pagination
You can now test pagination by visiting your API endpoint (e.g., http://127.0.0.1:8000/books/
).
- GET Request: When you make a GET request to
/books/
, the response will contain the first page of books with pagination metadata:
{
"count": 50,
"next": "http://127.0.0.1:8000/books/?page=2",
"previous": null,
"results": [
{
"id": 1,
"title": "Django for Beginners",
"author": "John Doe",
"published_date": "2020-01-01"
},
{
"id": 2,
"title": "Advanced Django",
"author": "Jane Smith",
"published_date": "2021-01-01"
}
]
}
This response tells you:
- The total number of books (
count
). - The URL to the next page (
next
). - The URL to the previous page (
previous
). - The list of books for the current page (
results
).
- Navigate to the Next Page: To get the next page of results, use the URL provided in the
next
field (?page=2
).
🧩 Step 6: Handling Custom Query Parameters
You can further customize how pagination works by allowing the client to pass in custom query parameters.
🛠️ Step 6.1: Custom Page Size
As mentioned before, you can let the client specify the page size by passing a page_size
parameter in the query string:
GET /books/?page=2&page_size=20
This request will return the second page with 20 books per page.
🧩 Step 7: Summary of Pagination Features
Feature | Explanation |
---|---|
PageNumberPagination | A simple way to paginate large sets of data using page numbers. |
Custom Pagination Class | Allows you to create a custom pagination style by subclassing DRF's built-in classes. |
page_size |
The number of items returned per page. |
next & previous |
Links to the next and previous pages, allowing clients to easily navigate. |
Custom Page Size | Clients can specify a custom page size by passing a page_size query parameter. |
Pagination Metadata | The paginated response includes metadata like count , next , and previous . |