0
0
DjangoHow-ToBeginner · 4 min read

How to Implement Ordering in Django REST Framework (DRF)

To implement ordering in Django REST Framework (DRF), add OrderingFilter to your view's filter_backends and specify ordering_fields or use ordering for default ordering. This allows clients to order API results by sending an ordering query parameter.
📐

Syntax

Use OrderingFilter in your DRF view's filter_backends. Define which fields can be ordered with ordering_fields. Optionally, set a default order with ordering.

  • filter_backends: List of filters applied to the view.
  • OrderingFilter: Enables ordering support.
  • ordering_fields: Fields allowed for ordering.
  • ordering: Default ordering if none specified by client.
python
from rest_framework import generics, filters
from myapp.models import Item
from myapp.serializers import ItemSerializer

class ItemListView(generics.ListAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    filter_backends = [filters.OrderingFilter]
    ordering_fields = ['name', 'price']  # fields clients can order by
    ordering = ['name']  # default ordering
💻

Example

This example shows a DRF API view that allows clients to order items by name or price. The default order is by name. Clients can request ?ordering=price or ?ordering=-price for descending order.

python
from rest_framework import generics, filters
from django.db import models
from rest_framework.serializers import ModelSerializer

# Model
class Item(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=6, decimal_places=2)

# Serializer
class ItemSerializer(ModelSerializer):
    class Meta:
        model = Item
        fields = ['id', 'name', 'price']

# View
class ItemListView(generics.ListAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    filter_backends = [filters.OrderingFilter]
    ordering_fields = ['name', 'price']
    ordering = ['name']
Output
GET /items/ # returns items ordered by name ascending GET /items/?ordering=price # returns items ordered by price ascending GET /items/?ordering=-price # returns items ordered by price descending
⚠️

Common Pitfalls

Common mistakes when implementing ordering in DRF include:

  • Not adding OrderingFilter to filter_backends, so ordering does not work.
  • Forgetting to specify ordering_fields, which restricts which fields clients can order by.
  • Using model fields not included in ordering_fields in the query parameter, which will be ignored.
  • Not handling descending order syntax with a leading -.
python
from rest_framework import generics, filters
from myapp.models import Item
from myapp.serializers import ItemSerializer

# Wrong: Missing OrderingFilter
class WrongView(generics.ListAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    filter_backends = []  # No OrderingFilter

# Right: Include OrderingFilter and ordering_fields
class RightView(generics.ListAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    filter_backends = [filters.OrderingFilter]
    ordering_fields = ['name', 'price']
📊

Quick Reference

FeatureDescriptionExample
filter_backendsList of filters applied to the view[filters.OrderingFilter]
OrderingFilterEnables ordering support in DRF viewsfilters.OrderingFilter
ordering_fieldsFields allowed for ordering by clients['name', 'price']
orderingDefault ordering if client does not specify['name']
Ordering query paramClient uses this to order results?ordering=price or ?ordering=-price

Key Takeaways

Add OrderingFilter to filter_backends to enable ordering in DRF views.
Specify ordering_fields to control which fields clients can order by.
Use the ordering attribute to set a default order for results.
Clients order results by adding ?ordering=field or ?ordering=-field to the URL.
Without OrderingFilter or ordering_fields, ordering will not work as expected.