A better DRF [Django REST Framework] serializer that normalizes nested objects into separate lists for improved performance
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_objectslook 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 ownrelated_objectsget 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
- Import the base class in your DRF serializers file:
from better_nested_serializer.serializers.model_serializer import BetterModelSerializer
- 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__"
- 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_objectsby their IDs. - If a nested serializer is also
BetterModelSerializer, it adds its related data into the samerelated_objectsblock.
Important notes
- Output only: this serializer is read‑only. It does not support
data=...,create,update, orvalidate. - Use
read_only=Truefor nested fields. - You can mix plain DRF serializers and
BetterModelSerializerwithout 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.
- Works fine. Each level adds its objects to
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file better_nested_serializer-0.1.6.tar.gz.
File metadata
- Download URL: better_nested_serializer-0.1.6.tar.gz
- Upload date:
- Size: 8.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2921c085a24d61c8a51af4ce26a5b5ab48300e2d86303e31cd1e4f65e7f2371
|
|
| MD5 |
779b26ef56158f77a406edc16cdcbcdd
|
|
| BLAKE2b-256 |
7249594074e9c5821797e05728ad4f5563fe25655152bc4dbda8f6ab0b20a3fb
|
File details
Details for the file better_nested_serializer-0.1.6-py3-none-any.whl.
File metadata
- Download URL: better_nested_serializer-0.1.6-py3-none-any.whl
- Upload date:
- Size: 7.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ae258d7ee5f8a9940ab390738ad82013c290f9bc0f6565a43338607b7f5df46
|
|
| MD5 |
721b2eb40bbfe344dad22d94350fdc0f
|
|
| BLAKE2b-256 |
5783d4642f5320b75d6585f8fbcbd5c1c745f0a50891b3ebc0b44505b4c3d01e
|