Using OrderingFilter in Django Rest Framework

Last updated 1 month, 1 week ago | 110 views 75     5

Tags:- Python Django DRF

When building APIs, clients often want to control the order in which data is returned—such as sorting blog posts by date or products by price. Django Rest Framework provides a built-in tool for this: OrderingFilter.

This article covers:

  • What OrderingFilter is

  • How it works

  • Step-by-step setup

  • Full working example

  • Tips and best practices

  • Common pitfalls


What is OrderingFilter?

OrderingFilter is a filter backend in DRF that allows API consumers to sort query results dynamically using a query parameter (usually ?ordering=).

It supports:

  • Ascending (?ordering=price)

  • Descending (?ordering=-price)

  • Multi-field ordering (?ordering=price,-name)

It’s part of the DRF core, so no third-party installation is required.


⚙️ How Does It Work?

You must:

  1. Add OrderingFilter to filter_backends in your view or globally.

  2. Define which fields can be used for ordering with ordering_fields.

  3. Optionally, define a default_ordering.


Step-by-Step: Implementing OrderingFilter

Step 1: Import and Configure

from rest_framework.filters import OrderingFilter

Step 2: Use It in Your View or ViewSet

from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
from rest_framework.filters import OrderingFilter

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = [OrderingFilter]
    ordering_fields = ['price', 'created_at', 'name']  # Allow sorting by these fields
    ordering = ['-created_at']  # Default order if none is specified

Step 3: Use in API Request

Examples:

  • Ascending:
    GET /api/products/?ordering=price

  • Descending:
    GET /api/products/?ordering=-price

  • Multiple fields:
    GET /api/products/?ordering=price,-name


✅ Full Working Example

models.py

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)

serializers.py

from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

views.py

from rest_framework import viewsets
from rest_framework.filters import OrderingFilter
from .models import Product
from .serializers import ProductSerializer

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = [OrderingFilter]
    ordering_fields = ['price', 'name', 'created_at']
    ordering = ['-created_at']

urls.py

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ProductViewSet

router = DefaultRouter()
router.register('products', ProductViewSet)

urlpatterns = [
    path('api/', include(router.urls)),
]

Tips and Best Practices

Tip Why It Helps
✅ Always define ordering_fields Prevents users from ordering by unintended fields
✅ Use indexes on fields used for ordering Speeds up database queries
✅ Set ordering for predictable defaults Improves UX when no param is passed
✅ Combine with SearchFilter or DjangoFilterBackend Adds more flexibility to your API

⚠️ Common Pitfalls

Pitfall Fix
❌ Ordering doesn't work Ensure OrderingFilter is in filter_backends
❌ Unexpected fields exposed Use ordering_fields to limit them
❌ Large queries are slow Add database indexes on sortable fields
❌ Using ordering without defined fields May expose sensitive data fields unintentionally

Combine with Other Filters

You can mix OrderingFilter with:

  • SearchFilter

  • DjangoFilterBackend

  • Custom filter backends

filter_backends = [SearchFilter, OrderingFilter, DjangoFilterBackend]

Conclusion

OrderingFilter is a simple yet powerful feature in Django Rest Framework that lets you expose dynamic sorting to your API consumers. Whether you're building product catalogs, blog feeds, or sortable dashboards, it's an essential tool for a better frontend experience.