Skip to main content

An optimized DRF [Django REST Framework] model serializer that normalizes nested objects into separate lists. This approach reduces JSON payload size and minimizes database queries by organizing related objects into distinct collections instead of duplicating them within parent objects.

Project description

better-nested-serializer

A tiny add‑on for Django REST Framework (DRF) that makes nested data smaller and easier to cache.

Simple idea:

  • In the main object, send only IDs for nested fields.
  • Put the full nested objects in one place called "related_objects".

This avoids repeating the same nested object many times and keeps responses small.

What the output looks like

When you use BetterModelSerializer, you get a response shaped like this:

{
  "object": {
    "id": 10,
    "title": "My Blog Post",
    "author": 3,
    "publisher": 2
  },
  "related_objects": {
    "test_app_author": {
      "3": { "id": 3, "name": "Ada" }
    },
    "test_app_publisher": {
      "2": { "id": 2, "name": "Tech Books" }
    }
  }
}

Notes:

  • Keys in related_objects look like <app_label>_<model_name> (for example: test_app_author).
  • Each value is a map of id -> full object.
  • If a nested serializer also uses BetterModelSerializer, its own related_objects get merged in.

Why this is helpful

  • Smaller payloads (no duplicated nested objects)
  • Easy client caching (each related object appears once by ID)
  • Clean split between the main object and related data

Requirements

  • Python 3.12+
  • Django REST Framework 3.16+
  • Django (a version supported by your DRF)

Install

pip install better-nested-serializer

Quick start

  1. Import the base class in your DRF serializers file:
from serializers.model_serializer import BetterModelSerializer
  1. Create your serializers. You can mix plain DRF serializers and BetterModelSerializer:
from rest_framework import serializers
from serializers.model_serializer import BetterModelSerializer
from .models import Author, Blog, Publisher

class PublisherSerializer(BetterModelSerializer):
    class Meta:
        model = Publisher
        fields = "__all__"

class AuthorSerializer(serializers.ModelSerializer):  # plain DRF serializer is fine
    class Meta:
        model = Author
        fields = "__all__"

class BlogSerializer(BetterModelSerializer):
    author = AuthorSerializer(read_only=True)        # nested: DRF serializer
    publisher = PublisherSerializer(read_only=True)  # nested: BetterModelSerializer

    class Meta:
        model = Blog
        fields = "__all__"
  1. Use it anywhere you serialize a model instance (view, viewset, etc.):
blog = Blog.objects.select_related("author", "publisher").get(pk=10)
serialized = BlogSerializer(blog)
Response(serialized.data)

Output example:

{
  "object": {
    "id": 10,
    "title": "My Blog Post",
    "author": 3,
    "publisher": 2
  },
  "related_objects": {
    "test_app_author": {
      "3": { "id": 3, "name": "Ada" }
    },
    "test_app_publisher": {
      "2": { "id": 2, "name": "Tech Books" }
    }
  }
}

Reverse relations (lists)

You can also serialize reverse relations (like author.blog_set). Example:

class BlogWithPublisherSerializer(BetterModelSerializer):
    publisher = PublisherSerializer(read_only=True)
    class Meta:
        model = Blog
        fields = "__all__"

class AuthorWithBlogsSerializer(BetterModelSerializer):
    blogs = BlogWithPublisherSerializer(many=True, read_only=True, source="blog_set")
    class Meta:
        model = Author
        fields = "__all__"

Sample output:

{
  "object": {
    "id": 3,
    "name": "Ada",
    "blogs": [10, 11, 12]
  },
  "related_objects": {
    "test_app_blog": {
      "10": { "id": 10, "title": "My Blog Post", "publisher": 2 },
      "11": { "id": 11, "title": "Another Post", "publisher": 2 },
      "12": { "id": 12, "title": "Last Post", "publisher": 5 }
    },
    "test_app_publisher": {
      "2": { "id": 2, "name": "Tech Books" },
      "5": { "id": 5, "name": "Daily News" }
    }
  }
}

How it works (in short)

  • The serializer returns 2 things: the main object and a map of related objects.
  • Nested fields become IDs in the main object.
  • The full nested objects are grouped under related_objects by their IDs.
  • If a nested serializer is also BetterModelSerializer, it adds its related data into the same related_objects block.

Important notes

  • Output only: this serializer is read‑only. It does not support data=..., create, update, or validate.
  • Use read_only=True for nested fields.
  • You can mix plain DRF serializers and BetterModelSerializer without problems.

FAQ

  • Can I POST with this serializer?

    • No. It’s for output only.
  • Do I need to change my models?

    • No. Use your existing Django models.
  • What about deep nesting?

    • Works fine. Each level adds its objects to related_objects.

License

MIT (or your project’s license).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

better_nested_serializer-0.1.0.tar.gz (4.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

better_nested_serializer-0.1.0-py3-none-any.whl (5.5 kB view details)

Uploaded Python 3

File details

Details for the file better_nested_serializer-0.1.0.tar.gz.

File metadata

File hashes

Hashes for better_nested_serializer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 32ce68794ad02a43c2435ae74523fa5fb0b8d93cd450d05ba035bab54a7726c1
MD5 14b55b5d307991cfc85457c97cd2e64b
BLAKE2b-256 02b53ae4a68e38c41ed25b97fa1e448b8cc14d022228ccdd5430d71cc758a952

See more details on using hashes here.

File details

Details for the file better_nested_serializer-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for better_nested_serializer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 494cf8a7f007095e041f58fb9fd051e634d32bd35905025052618ed7c16b71f5
MD5 c48ef096ababa0ba1bbbff15a956ceb6
BLAKE2b-256 4c88981883580eccc29ace26ae3f47b9c365308420d51ed21dc382d7dc06a1de

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page