Enabling and Customizing Pagination in Django REST Framework
Learn how to enable global pagination in Django REST Framework, see a concrete settings.py and view example, understand limits, and avoid common pitfalls.
21 Sept 2026, 11:15 UTC

Quick answer
To get paginated lists from a DRF view, add a global pagination class and page size in settings.py. Any ListAPIView or ViewSet that returns a queryset will then automatically wrap the data in results, next, previous and count fields.
How it works
DRF’s pagination classes sit between the queryset and the serializer. When a request arrives, the view calls paginate_queryset on the chosen class, which slices the queryset according to the page query parameter (or page_size if overridden) and returns a page object. The view then serializes that page and the pagination class adds the navigation links.
Worked configuration
1. Global settings
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20,
'MAX_PAGE_SIZE': 100,
}Place this block near the bottom of your settings.py file. No restart is required if you are using Django’s auto‑reloader; otherwise reload the development server.
2. Example view
# views.py
from rest_framework import generics
from myapp.models import Article
from myapp.serializers import ArticleSerializer
class ArticleListView(generics.ListAPIView):
queryset = Article.objects.all().order_by('published_at')
serializer_class = ArticleSerializer
# pagination is inherited from settings; you could override here if needed
Save the file; the view will now use the global pagination class.
Limits and common mistakes
Limits
- Default PAGE_SIZE is 20; clients can request more with
?page_size=50up toMAX_PAGE_SIZE. - Counting total items adds a
SELECT COUNT(*)query unless you setcount=Falseon the pagination class. - Cursor pagination (e.g.,
rest_framework.pagination.CursorPagination) ignores ordering changes and requires a unique, immutable ordering field.
Common mistakes
- Omitting
DEFAULT_PAGINATION_CLASSor setting it toNone; then views return the full queryset. - Expecting pagination on plain Python lists; DRF only paginates querysets.
- Confusing query parameters: the default class uses
pagefor the page number andpage_sizefor overriding size. - Setting
PAGE_SIZEtoo high without indexes, causing heavy DB load.
Verification
- Start the development server:
python manage.py runserver(run in the project directory; needs read/write access to the project folder). - Request the list endpoint:
GET /api/articles/?page=2(adjust the URL to your view). - Check the JSON response: it should contain
results(array),next(URL or null),previous(URL or null) andcount(integer). The length ofresultsshould equalPAGE_SIZEunless it is the final page. - Optional: run a quick shell test:
python manage.py shell >>> from rest_framework.pagination import PageNumberPagination >>> from myapp.models import Article >>> paginator = PageNumberPagination() >>> page = paginator.paginate_queryset(Article.objects.all(), None) >>> print(page.number, paginator.page.paginator.num_pages) - If the response lacks pagination keys, verify that
DEFAULT_PAGINATION_CLASSis set correctly and that the view inherits from a generic list view or a ViewSet withlistaction.
Rollback
Changing settings.py modifies the application state. To revert, remove or comment out the REST_FRAMEWORK block and restart the server. No database migration is needed.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.