Paramclasses Academy - Blog

Tutorials Details

←
Post 25 of 29
→

Django REST Framework Pagination, Filtering, Searching, and Ordering: Efficient API Data Management and Query Optimization

Django REST Framework Pagination, Filtering, Searching, and Ordering: Efficient API Data Management and Query Optimization

October 21, 2026

Introduction

Pagination, Filtering, Searching, and Ordering are important features in Django REST Framework (DRF) that help developers manage large datasets efficiently.

Imagine a Student Management System containing thousands of student records. Returning every record in a single API response can increase response size, consume unnecessary bandwidth, and make the application slower.

Pagination divides large datasets into smaller pages. Filtering retrieves records that match specific conditions. Searching helps users find records using keywords, and Ordering sorts records according to selected fields.

In this module, you will learn how to implement these features in a Student Management API using Django REST Framework.

What You Will Learn

  • What pagination is and why it is useful.

  • How to configure pagination globally.

  • How to use PageNumberPagination.

  • How to use LimitOffsetPagination.

  • How to filter records using query parameters.

  • How to implement search using SearchFilter.

  • How to sort records using OrderingFilter.

  • How to combine filtering, searching, and ordering.

  • How to customize pagination settings.

  • How to test API query parameters.

1. Understanding Pagination

Pagination divides a large collection of records into smaller groups called pages.

For example, if your database contains 1,000 student records, you can return only 10 records per page.

Instead of returning all 1,000 records at once, the API returns a manageable number of records along with pagination information.

Benefits of Pagination

  • Reduces the size of individual API responses.

  • Helps improve response times for large collections.

  • Reduces unnecessary data transfer.

  • Makes frontend data tables easier to manage.

  • Provides convenient page navigation.

Example:

/api/students/?page=1
/api/students/?page=2
/api/students/?page=3

Each URL requests a different page of student records.

2. Configuring Global Pagination

Open your project's settings.py.

Add or update the REST_FRAMEWORK configuration:

REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": (
        "rest_framework.pagination.PageNumberPagination"
    ),
    "PAGE_SIZE": 10,
}

Explanation:

  • DEFAULT_PAGINATION_CLASS specifies the pagination class used by default.

  • PageNumberPagination divides results into numbered pages.

  • PAGE_SIZE = 10 returns up to 10 records per page.

If your project already contains a REST_FRAMEWORK dictionary, add these settings to it rather than creating a duplicate dictionary.

Pagination applies to compatible list views when the relevant configuration is enabled.

3. Understanding PageNumberPagination

PageNumberPagination allows clients to retrieve records using page numbers.

Example endpoint:

http://127.0.0.1:8000/api/students/?page=1

To retrieve the next page:

http://127.0.0.1:8000/api/students/?page=2

A typical paginated response looks like this:

{
    "count": 25,
    "next": "http://127.0.0.1:8000/api/students/?page=2",
    "previous": null,
    "results": [
        {
            "id": 1,
            "name": "Rahul Sharma",
            "email": "rahul@example.com",
            "course": "Python"
        }
    ]
}

Understanding the response:

  • count indicates the total number of matching records.

  • next provides the next page URL, if available.

  • previous provides the previous page URL, if available.

  • results contains the records for the current page.

The number of records in results depends on the page size and how many records remain.

4. Creating Custom Pagination

Sometimes, you want to control the pagination behavior for a particular API.

Create a file named students/pagination.py:

from rest_framework.pagination import PageNumberPagination


class StudentPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = "page_size"
    max_page_size = 50

Explanation:

  • page_size = 10 sets the default number of records per page.

  • page_size_query_param = "page_size" allows clients to request a different page size.

  • max_page_size = 50 limits the maximum requested page size.

For example:

/api/students/?page=2&page_size=20

This requests page 2 with up to 20 records.

Requests exceeding the configured maximum are capped at 50 records per page.

To apply this pagination class to a ViewSet:

from rest_framework import viewsets
from .models import Student
from .serializers import StudentSerializer
from .pagination import StudentPagination


class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all().order_by("id")
    serializer_class = StudentSerializer
    pagination_class = StudentPagination

5. Understanding LimitOffsetPagination

Another pagination option is LimitOffsetPagination.

Instead of using page numbers, it uses two parameters:

  • limit: the maximum number of records to return.

  • offset: the number of records to skip before returning results.

Example:

/api/students/?limit=10&offset=0

This requests up to 10 records, starting from the first record.

To retrieve the next group:

/api/students/?limit=10&offset=10

Configure it globally in settings.py:

REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": (
        "rest_framework.pagination.LimitOffsetPagination"
    ),
    "PAGE_SIZE": 10,
}

Important: This configuration replaces the global pagination class shown in the previous examples. Do not define multiple competing REST_FRAMEWORK dictionaries.

PageNumberPagination vs LimitOffsetPagination

Feature PageNumberPagination LimitOffsetPagination
Main parameters page limit, offset
Navigation Numbered pages Number of records and starting offset
Example ?page=2 ?limit=10&offset=10
Common use Standard page-based listings APIs that need offset-based retrieval

Choose the pagination style that best suits your API and frontend requirements.

6. Understanding Filtering

Filtering allows users to retrieve records that match specific conditions.

For example, a Student Management API may allow users to retrieve only students enrolled in a particular course.

Example:

/api/students/?course=Python

This URL represents a request to retrieve students whose course is Python, provided the API has been configured to support that filter.

DRF supports filtering through query parameters, custom querysets, and filtering backends.

7. Implementing Filtering with DjangoFilterBackend

For advanced filtering, you can use the django-filter package.

Install it:

pip install django-filter

Add the application to INSTALLED_APPS in settings.py:

INSTALLED_APPS = [
    # Existing applications
    "django_filters",
]

Now configure the Student ViewSet:

from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from .models import Student
from .serializers import StudentSerializer


class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all().order_by("id")
    serializer_class = StudentSerializer

    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["course"]

This enables exact-match filtering by the course field.

Example requests:

/api/students/?course=Python
/api/students/?course=Django

The API returns records that match the specified course.

Important: A filter field must exist on the model or be explicitly configured as a valid filter. Do not expose sensitive fields as public filters without considering access control.

8. Implementing Search with SearchFilter

SearchFilter enables keyword-based searching across configured fields.

For example, users may want to search students by name, email, or course.

Update the ViewSet:

from rest_framework import viewsets, filters
from .models import Student
from .serializers import StudentSerializer


class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all().order_by("id")
    serializer_class = StudentSerializer

    filter_backends = [filters.SearchFilter]
    search_fields = ["name", "email", "course"]

Example search requests:

/api/students/?search=Rahul
/api/students/?search=Python
/api/students/?search=example.com

Explanation:

  • SearchFilter processes the search query parameter.

  • search_fields identifies the fields that can be searched.

  • Search behavior is case-insensitive by default for standard text fields.

This makes it easier to build searchable tables and directory pages.

Searching Across Multiple Fields

With the configuration above, a search term can match any configured search field.

For example, searching for Python can return students whose name, email, or course contains a matching term.

Use only fields that are appropriate for the intended audience.

9. Implementing Ordering with OrderingFilter

Ordering allows clients to sort API results by selected fields.

For example, students may need to be sorted alphabetically by name or by email.

Configure the ViewSet:

from rest_framework import viewsets, filters
from .models import Student
from .serializers import StudentSerializer


class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

    filter_backends = [filters.OrderingFilter]
    ordering_fields = ["name", "email", "id"]
    ordering = ["id"]

Example requests:

/api/students/?ordering=name
/api/students/?ordering=-name
/api/students/?ordering=email

Explanation:

  • ordering_fields defines the fields clients are allowed to sort by.

  • ordering = ["id"] defines the default ordering.

  • ordering=name sorts in ascending order.

  • ordering=-name sorts in descending order.

Security best practice: Explicitly define ordering_fields rather than allowing arbitrary model fields to be used for ordering.

10. Combining Filtering, Searching, and Ordering

A practical API often needs all three features.

Update students/views.py:

from rest_framework import viewsets, filters
from django_filters.rest_framework import DjangoFilterBackend
from .models import Student
from .serializers import StudentSerializer
from .pagination import StudentPagination


class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

    pagination_class = StudentPagination

    filter_backends = [
        DjangoFilterBackend,
        filters.SearchFilter,
        filters.OrderingFilter,
    ]

    filterset_fields = ["course"]
    search_fields = ["name", "email", "course"]
    ordering_fields = ["name", "email", "id"]
    ordering = ["id"]

This ViewSet combines:

  • Pagination using StudentPagination.

  • Filtering by course.

  • Searching by name, email, or course.

  • Ordering by approved fields.

Example request:

/api/students/?course=Python&search=Rahul&ordering=name&page=1&page_size=10

The API applies the configured filtering, searching, and ordering, then paginates the matching results.

Important: This example assumes the StudentPagination class and django-filter package have been created and installed as described earlier.

11. Understanding Query Parameters

Query parameters are values supplied in the URL after the question mark (?).

Multiple parameters are separated by ampersands (&).

Example:

/api/students/?course=Python&ordering=name&page=2

Here:

  • course=Python filters records by course.

  • ordering=name sorts the results by name.

  • page=2 requests the second page.

Query parameters let frontend applications change API results without creating a separate endpoint for every combination.

12. Understanding the API Request Flow

When a client requests a filtered and paginated endpoint, the process generally works as follows:

  1. The client sends an HTTP request containing query parameters.

  2. Django resolves the URL to the appropriate ViewSet.

  3. DRF obtains the ViewSet's queryset.

  4. Configured filter backends apply the requested filters, search terms, and ordering.

  5. Pagination divides the resulting collection into pages.

  6. The serializer converts the selected records into API-compatible data.

  7. DRF returns the response.

This process helps keep API logic organized and reusable.

13. Testing with Postman or the Browsable API

You can test these features through the DRF browsable API, Postman, or another API client.

Use the following examples:

Retrieve the first page:

GET /api/students/?page=1

Filter by course:

GET /api/students/?course=Python

Search by name:

GET /api/students/?search=Rahul

Sort by name:

GET /api/students/?ordering=name

Combine multiple features:

GET /api/students/?course=Python&search=Rahul&ordering=-name&page=1&page_size=10

Check that the results match the requested conditions and that pagination metadata is correct.

If the endpoint requires authentication, include the appropriate authentication credentials.

14. Common Errors and Solutions

Error 1: ModuleNotFoundError: No module named 'django_filters'

Solution: Install the package using pip install django-filter and add django_filters to INSTALLED_APPS.

Error 2: Search parameters have no effect

Solution: Verify that SearchFilter is configured and that search_fields contains the intended fields.

Error 3: Filtering returns all records

Solution: Confirm that DjangoFilterBackend is configured and that the requested field is listed in filterset_fields or a custom filter set.

Error 4: Ordering parameter is ignored

Solution: Check that OrderingFilter is enabled and the requested field appears in ordering_fields.

Error 5: Pagination is not working

Solution: Verify the pagination class and page-size configuration. Also confirm that you are requesting a list endpoint that supports pagination.

Error 6: Invalid page number

Solution: Use a valid page number. Depending on the configuration and request, DRF may return a validation error when the page does not exist.

Error 7: Unexpected duplicate records

Solution: Review queryset joins and ordering. If necessary, adjust the queryset to ensure records are unique.

Error 8: API responses are still too slow

Solution: Pagination reduces response size but does not automatically optimize database queries. Review database indexes, query counts, and queryset performance.

15. Frequently Asked Questions (FAQs)

Q1. What is pagination in Django REST Framework?

Pagination divides large API result sets into smaller pages.

Q2. What is the difference between filtering and searching?

Filtering selects records based on specific conditions, while searching finds records that match a keyword or search expression.

Q3. What is the purpose of SearchFilter?

It enables keyword-based searching across fields configured in search_fields.

Q4. What is the purpose of OrderingFilter?

It allows clients to sort results using approved fields.

Q5. What is DjangoFilterBackend?

It integrates the django-filter package with DRF to support field-based filtering.

Q6. Can filtering, searching, and ordering be used together?

Yes. Configure multiple filter backends on the same API view or ViewSet.

Q7. What is the difference between PageNumberPagination and LimitOffsetPagination?

Page-number pagination uses a page number, while limit-offset pagination uses a result limit and starting offset.

Q8. Does pagination automatically make every query fast?

No. It reduces the number of records returned per response, but database query optimization may still be necessary.

Q9. Can users choose the page size?

Yes, if the pagination class is configured with page_size_query_param. A maximum page size can limit the requested value.

16. Django REST Framework Interview Questions and Answers

Q1. What is pagination?

Answer: Pagination divides a large collection of API results into smaller groups to make responses easier to manage.

Q2. What is PageNumberPagination?

Answer: It allows clients to navigate through results using page numbers.

Q3. What is LimitOffsetPagination?

Answer: It uses limit and offset parameters to control the number of returned records and the starting position.

Q4. What is SearchFilter?

Answer: It is a DRF filtering backend that supports keyword-based searching across configured fields.

Q5. What is OrderingFilter?

Answer: It enables sorting of API results using configured ordering fields.

Q6. What is the purpose of filterset_fields?

Answer: It specifies model fields that can be used for filtering with DjangoFilterBackend.

Q7. How can multiple filtering features be combined?

Answer: Configure DjangoFilterBackend, SearchFilter, and OrderingFilter together in filter_backends.

Q8. Why should ordering_fields be explicitly configured?

Answer: It limits which fields clients can use for ordering and helps prevent unintended access to internal model fields.

17. Practical Assignment

Build a Student Management API with Pagination, Filtering, Searching, and Ordering.

Requirements:

  1. Create or reuse the Student model with name, email, and course.

  2. Create a StudentSerializer.

  3. Implement a StudentViewSet.

  4. Configure PageNumberPagination.

  5. Allow clients to choose a page size with a maximum limit.

  6. Install and configure django-filter.

  7. Add filtering by course.

  8. Add searching by name, email, and course.

  9. Add ordering by name, email, and ID.

  10. Combine multiple query parameters in a single request.

  11. Test the endpoints using Postman or the browsable API.

  12. Test invalid page numbers and unsupported ordering fields.

  13. Verify that authentication and permissions still work correctly.

Expected Result:

You should have a Student Management API that returns manageable pages of data and supports filtering, searching, and ordering through query parameters.

Conclusion

In this module, you learned how Django REST Framework Pagination, Filtering, Searching, and Ordering help manage API data efficiently. You explored PageNumberPagination, LimitOffsetPagination, DjangoFilterBackend, SearchFilter, and OrderingFilter.

You also learned how to combine these features in a ViewSet, customize page sizes, test query parameters, and identify common API issues.

In the next module, you will learn about Django REST Framework API Testing and Documentation, including automated API tests, testing CRUD endpoints, and documenting APIs with tools such as Swagger and OpenAPI.

←
Post 25 of 29
→