How to Use pandas in Django REST Framework

Uncategorized

A Practical Guide to Building Flexible APIs with APIView

Introduction: There’s surprisingly little information about using pandas in DRF

Most Django REST Framework (DRF) tutorials focus on:

  • simple CRUD operations
  • returning model data directly
  • using ModelSerializer

But in real-world projects, what you need most often are:

  • analytics APIs
  • data transformation APIs
  • visualization-ready APIs
  • multi-table aggregation APIs

These rarely return raw database rows.

This is exactly where pandas becomes incredibly useful.

However, there are very few high-quality guides explaining
“How do I properly use pandas inside DRF?”

This article introduces:

  • Why pandas works so well with DRF
  • Why APIView is the best choice when using pandas
  • Safe patterns for converting Querysets into DataFrames
  • Practical examples (raw data, monthly aggregation, Recharts formatting, dashboards)

Why pandas is a perfect match for REST APIs

pandas is designed for data analytics, but its strengths map beautifully to REST API use cases.

✔ Strengths of pandas

  • Easy aggregation (groupby, pivot_table, resample)
  • Clean handling of missing values
  • Powerful type conversions (datetime, numeric, category)
  • Simple column renaming
  • Easy JSON shaping with to_dict()

✔ Strengths of DRF

  • Routing
  • Authentication and permissions
  • Request/response handling
  • API schema support

Combined, they form a powerful workflow:

Queryset → DataFrame → processing → dict → Response

This pattern is ideal for dashboard- and analytics-oriented APIs.

Why APIView works better than ViewSet when using pandas

ViewSet is optimized for:

  • CRUD
  • ModelSerializer
  • returning data in model-like shapes

But analytics APIs need:

  • custom aggregations
  • multi-table joins
  • deeply customized JSON output
  • time-series processing
  • transformations unrelated to the DB model

In other words, you need freedom.

→ APIView provides exactly that

  • You write plain Python logic
  • No serializer constraints
  • Easy to integrate with pandas
  • Clearer control over input and output

For pandas-heavy APIs, APIView is simply the best option.


How to convert Querysets into pandas DataFrames safely

This is the core operation when working with pandas in DRF.

Basic pattern

qs = Model.objects.all().values()
df = pd.DataFrame(qs)

Best practice: select only the columns you need

qs = Sales.objects.all().values("area", "amount", "date")
df = pd.DataFrame(qs)

Benefits:

  • Better performance
  • No unnecessary data leakage
  • Easier debugging
  • Cleaner DataFrame structures

Example 1: A simple API that returns raw data

class RawSalesAPIView(APIView):
    def get(self, request):
        qs = Sales.objects.all().values("area", "amount", "date")
        df = pd.DataFrame(qs)

        # Convert date to string for frontend compatibility
        df["date"] = df["date"].astype(str)

        return Response(df.to_dict(orient="records"))

Why this matters

  • Avoids datetime serialization issues
  • Provides stable, predictable JSON
  • Easy to extend with transformations later

Example 2: Monthly aggregation API (common analytics use case)

class MonthlySalesAPIView(APIView):
    def get(self, request):
        qs = Sales.objects.all().values("date", "amount")
        df = pd.DataFrame(qs)

        df["date"] = pd.to_datetime(df["date"])

        monthly = (
            df.groupby(df["date"].dt.to_period("M"))["amount"]
              .sum()
              .reset_index()
        )

        monthly["date"] = monthly["date"].astype(str)

        return Response(monthly.to_dict(orient="records"))

Example JSON output

[
  {"date": "2025-01", "amount": 3200},
  {"date": "2025-02", "amount": 4100}
]

Perfect for line charts or bar charts in React/Recharts.

Example 3: Formatting data for a Recharts PieChart

Recharts expects:

[
  {"name": "Area A", "value": 30},
  {"name": "Area B", "value": 40}
]

Your backend can generate that easily:

class AreaSharePieAPIView(APIView):
    def get(self, request):
        qs = Sales.objects.all().values("area", "share")
        df = pd.DataFrame(qs)

        result = (
            df.groupby("area")["share"]
              .mean()
              .reset_index()
              .rename(columns={"area": "name", "share": "value"})
        )

        return Response(result.to_dict(orient="records"))

Why pandas is ideal

  • groupby operations are simple
  • column renaming is flexible
  • JSON output is perfectly shaped

Example 4: Returning multiple datasets in a single dashboard API

This is extremely common in dashboards.

class DashboardAPIView(APIView):
    def get(self, request):
        qs = Sales.objects.all().values()
        df = pd.DataFrame(qs)

        total = df["amount"].sum()
        by_area = df.groupby("area")["amount"].sum().reset_index()
        by_target = df.groupby("target")["amount"].sum().reset_index()

        return Response({
            "total": int(total),
            "by_area": by_area.to_dict(orient="records"),
            "by_target": by_target.to_dict(orient="records"),
        })

This single endpoint can power multiple charts.

Best practices when using pandas in DRF

✔ Convert datetime to string

React/Recharts often fail with Python datetime objects.

✔ Use fillna(0) to prevent frontend crashes

Missing values are dangerous in JS chart libraries.

✔ Always return orient="records"

The most compatible JSON structure.

✔ Prefer APIView over ViewSet for analytics

Cleaner logic and fewer constraints.

✔ Split complex transformations into helper functions

Improves maintainability and testability.

When not to use pandas

Serializer-based DRF shines when:

  • Your API performs CRUD
  • You need input validation (POST/PUT/PATCH)
  • Output matches your database model
  • You rely heavily on auto-generated API schemas

For analytics, pandas is almost always the better tool.

Conclusion: pandas + APIView is the perfect stack for analytics APIs

pandas handles transformation and structure.
DRF handles API mechanics and security.

Together they create an ideal environment for:

  • dashboards
  • aggregated analytics
  • competitor comparisons
  • segmentation metrics
  • chart-ready datasets

If you’ve ever struggled with Serializers for data-heavy APIs,
try using pandas inside APIView.

You’ll find that your code becomes cleaner, faster, and far easier to maintain.