Bird
Raised Fist0
Djangoframework~5 mins

Pagination (PageNumber, Cursor, Limit/Offset) in Django

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction

Pagination helps split large lists of data into smaller parts. This makes pages load faster and easier to read.

Showing a list of blog posts on a website with many entries.
Displaying search results where there are too many items to show at once.
Loading user comments in chunks to avoid slow page loading.
Browsing products in an online store with many items.
Fetching data from an API that returns large datasets.
Syntax
Django
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.

Examples
This sets up pagination to show 5 items per page using page numbers.
Django
class MyPageNumberPagination(PageNumberPagination):
    page_size = 5
This uses cursor pagination ordered by 'id' with 5 items per page.
Django
class MyCursorPagination(CursorPagination):
    page_size = 5
    ordering = 'id'
This sets limit-offset pagination with a default of 5 items and max 20 items per request.
Django
class MyLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 5
    max_limit = 20
Sample Program

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.

Django
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)
OutputSuccess
Important Notes

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.

Summary

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

(1/5)
1. Which Django REST Framework pagination style uses a page number to fetch specific pages of data?
easy
A. PageNumberPagination
B. CursorPagination
C. LimitOffsetPagination
D. OffsetPagination

Solution

  1. Step 1: Understand pagination styles

    PageNumberPagination uses page numbers like 1, 2, 3 to get data pages.
  2. Step 2: Match style to description

    CursorPagination uses a cursor token, LimitOffsetPagination uses limit and offset numbers, so they don't use page numbers.
  3. Final Answer:

    PageNumberPagination -> Option A
  4. Quick Check:

    Page number style = PageNumberPagination [OK]
Hint: PageNumberPagination uses simple page numbers like 1, 2, 3 [OK]
Common Mistakes:
  • Confusing CursorPagination with page numbers
  • Thinking LimitOffsetPagination uses page numbers
  • Assuming OffsetPagination is a valid DRF style
2. Which of the following is the correct way to set LimitOffsetPagination in Django REST Framework settings?
easy
A. "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.OffsetPagination"
B. "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination"
C. "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination"
D. "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.CursorPagination"

Solution

  1. Step 1: Identify correct class path

    LimitOffsetPagination is located at rest_framework.pagination.LimitOffsetPagination.
  2. Step 2: Verify syntax for settings

    The setting key is DEFAULT_PAGINATION_CLASS and the value is the full class path as a string.
  3. Final Answer:

    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination" -> Option C
  4. Quick Check:

    Correct class path and setting key = "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination" [OK]
Hint: Use full class path string for pagination in settings [OK]
Common Mistakes:
  • Using OffsetPagination which does not exist
  • Missing quotes around class path string
  • Mixing pagination class names
3. Given this code snippet using CursorPagination, what will be the value of the next cursor if the current cursor is 'abc123' and page size is 2?
class MyCursorPagination(CursorPagination):
    page_size = 2

paginator = MyCursorPagination()
next_cursor = paginator.get_next_link()
medium
A. A tuple with offset and limit values
B. An integer representing the next page number
C. None, because get_next_link() returns nothing
D. A URL containing a cursor parameter with a new encoded cursor

Solution

  1. Step 1: Understand CursorPagination behavior

    CursorPagination returns URLs with encoded cursor tokens for next pages, not page numbers or tuples.
  2. Step 2: Analyze get_next_link() output

    get_next_link() returns a URL string containing the next cursor parameter for pagination.
  3. Final Answer:

    A URL containing a cursor parameter with a new encoded cursor -> Option D
  4. Quick Check:

    CursorPagination next link = URL with cursor [OK]
Hint: CursorPagination returns URLs with cursor tokens, not numbers [OK]
Common Mistakes:
  • Expecting page numbers from CursorPagination
  • Thinking get_next_link() returns None
  • Confusing limit/offset with cursor
4. You have this Django REST Framework view using LimitOffsetPagination but it raises an error:
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?
medium
A. pagination_class should be a string path, not a class
B. default_limit should be an integer, not a string
C. ListAPIView does not support pagination
D. queryset must be a list, not a QuerySet

Solution

  1. Step 1: Check default_limit type

    default_limit must be an integer, but it is set as a string '10', causing a type error.
  2. Step 2: Verify other parts

    pagination_class can be a class, ListAPIView supports pagination, queryset can be a QuerySet.
  3. Final Answer:

    default_limit should be an integer, not a string -> Option B
  4. Quick Check:

    default_limit type error = default_limit should be an integer, not a string [OK]
Hint: default_limit must be int, not quoted string [OK]
Common Mistakes:
  • Setting default_limit as string instead of int
  • Thinking pagination_class must be string path
  • Assuming ListAPIView disables pagination
5. You want to implement pagination for a large dataset where new items are frequently added. Which pagination style is best to avoid duplicate or missing items when users navigate pages?
hard
A. CursorPagination
B. PageNumberPagination
C. LimitOffsetPagination
D. No pagination

Solution

  1. Step 1: Understand pagination challenges with dynamic data

    PageNumber and LimitOffset can cause duplicates or missing items if data changes between requests.
  2. 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.
  3. Final Answer:

    CursorPagination -> Option A
  4. Quick Check:

    Dynamic data needs CursorPagination [OK]
Hint: Use CursorPagination for changing data to avoid duplicates [OK]
Common Mistakes:
  • Choosing PageNumberPagination for dynamic data
  • Thinking LimitOffsetPagination handles data changes well
  • Ignoring pagination for large datasets