Pagination helps split large lists of data into smaller parts. This makes pages load faster and easier to read.
Pagination (PageNumber, Cursor, Limit/Offset) in Django
Start learning this pattern below
Jump into concepts and practice - no test required
from rest_framework.pagination import PageNumberPagination, CursorPagination, LimitOffsetPagination # PageNumberPagination example class MyPageNumberPagination(PageNumberPagination): page_size = 10 # CursorPagination example class MyCursorPagination(CursorPagination): page_size = 10 ordering = '-created' # LimitOffsetPagination example class MyLimitOffsetPagination(LimitOffsetPagination): default_limit = 10 max_limit = 50
PageNumberPagination uses page numbers like ?page=2.
CursorPagination uses a cursor string to keep track of position, good for changing data.
class MyPageNumberPagination(PageNumberPagination): page_size = 5
class MyCursorPagination(CursorPagination): page_size = 5 ordering = 'id'
class MyLimitOffsetPagination(LimitOffsetPagination): default_limit = 5 max_limit = 20
This example shows a simple API view that paginates a list of fruit names using page number pagination with 3 items per page.
When you request the API with ?page=1, it returns the first 3 fruits. With ?page=2, it returns the next 3, and so on.
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.pagination import PageNumberPagination from rest_framework import status class ItemListView(APIView): class MyPagination(PageNumberPagination): page_size = 3 pagination_class = MyPagination() def get(self, request): items = ['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig', 'grape'] paginator = self.pagination_class page = paginator.paginate_queryset(items, request) return paginator.get_paginated_response(page)
PageNumberPagination is simple and good for static data.
CursorPagination is better for data that changes often because it avoids duplicates or missing items.
LimitOffsetPagination lets clients control how many items to get and where to start.
Pagination splits big data into smaller pages for easier loading and viewing.
Django REST Framework offers PageNumber, Cursor, and LimitOffset pagination styles.
Choose the pagination type based on your data and user needs.
Practice
Solution
Step 1: Understand pagination styles
PageNumberPagination uses page numbers like 1, 2, 3 to get data pages.Step 2: Match style to description
CursorPagination uses a cursor token, LimitOffsetPagination uses limit and offset numbers, so they don't use page numbers.Final Answer:
PageNumberPagination -> Option AQuick Check:
Page number style = PageNumberPagination [OK]
- Confusing CursorPagination with page numbers
- Thinking LimitOffsetPagination uses page numbers
- Assuming OffsetPagination is a valid DRF style
Solution
Step 1: Identify correct class path
LimitOffsetPagination is located at rest_framework.pagination.LimitOffsetPagination.Step 2: Verify syntax for settings
The setting key is DEFAULT_PAGINATION_CLASS and the value is the full class path as a string.Final Answer:
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination" -> Option CQuick Check:
Correct class path and setting key = "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination" [OK]
- Using OffsetPagination which does not exist
- Missing quotes around class path string
- Mixing pagination class names
class MyCursorPagination(CursorPagination):
page_size = 2
paginator = MyCursorPagination()
next_cursor = paginator.get_next_link()
Solution
Step 1: Understand CursorPagination behavior
CursorPagination returns URLs with encoded cursor tokens for next pages, not page numbers or tuples.Step 2: Analyze get_next_link() output
get_next_link() returns a URL string containing the next cursor parameter for pagination.Final Answer:
A URL containing a cursor parameter with a new encoded cursor -> Option DQuick Check:
CursorPagination next link = URL with cursor [OK]
- Expecting page numbers from CursorPagination
- Thinking get_next_link() returns None
- Confusing limit/offset with cursor
class MyLimitOffsetPagination(LimitOffsetPagination):
default_limit = '10'
class MyView(ListAPIView):
pagination_class = MyLimitOffsetPagination
queryset = MyModel.objects.all()
serializer_class = MySerializer
What is the likely cause of the error?
Solution
Step 1: Check default_limit type
default_limit must be an integer, but it is set as a string '10', causing a type error.Step 2: Verify other parts
pagination_class can be a class, ListAPIView supports pagination, queryset can be a QuerySet.Final Answer:
default_limit should be an integer, not a string -> Option BQuick Check:
default_limit type error = default_limit should be an integer, not a string [OK]
- Setting default_limit as string instead of int
- Thinking pagination_class must be string path
- Assuming ListAPIView disables pagination
Solution
Step 1: Understand pagination challenges with dynamic data
PageNumber and LimitOffset can cause duplicates or missing items if data changes between requests.Step 2: Identify pagination style that handles dynamic data well
CursorPagination uses a stable cursor based on item order, preventing duplicates or skips when data changes.Final Answer:
CursorPagination -> Option AQuick Check:
Dynamic data needs CursorPagination [OK]
- Choosing PageNumberPagination for dynamic data
- Thinking LimitOffsetPagination handles data changes well
- Ignoring pagination for large datasets
