Dynamic serializer configuration for Django REST Framework - Shape your API responses at runtime.drf-shapeless-serializers revolutionizes API development by giving you runtime serializer superpowers. Instead of creating multiple serializer classes , configure everything on the fly with one serializer to rule them all.Now you can shape your serializers like Lego cubes - rearranging fields, nesting relationships, and transforming outputs dynamically with unlimited flexibility.
Project description
DRF-Shapeless-Serializers Package
Motivation
Tired of serializer hell? Every Django REST Framework developer knows the pain of creating countless serializer variations for slightly different API endpoints, duplicating code for simple field variations, struggling with rigid and complex nested relationships, and maintaining sprawling serializer classes.
What if you could eliminate 80% of your serializer code? drf-shapeless-serializers revolutionizes API development by giving you runtime serializer superpowers. Instead of creating multiple serializer classes , configure everything on the fly with one serializer to rule them all.
Now you can shape your serializers like Lego cubes - rearranging fields, nesting relationships, and transforming outputs dynamically with unlimited flexibility.
Overview
drf-shapeless-serializers provides powerful mixins that extend Django REST Framework's serializers with dynamic configuration capabilities. By inheriting from our base classes, you can select fields at runtime, rename output keys dynamically, modify field attributes per-request, add and configure nested relationships on-the-fly and apply conditional field logic.
All without creating multiple serializer classes and annoying nested relations.
Installation
pip install drf-shapeless-serializers
**Add to your Django settings:
INSTALLED_APPS = [
# ... other apps
'shapeless_serializers',
]
Usage
Basic Setup
- Define your shapeless serializer:
from shapeless_serializers.serializers import ShapelessModelSerializer
class UserSerializer(ShapelessModelSerializer):
class Meta:
model = User
fields = '__all__'
class AuthorSerializer(ShapelessModelSerializer):
class Meta:
model = Author
fields = '__all__'
class BookSerializer(ShapelessModelSerializer):
class Meta:
model = Book
fields = '__all__'
- Configure dynamically in views:
def book_detail(request, pk):
book = Book.objects.get(pk=pk)
serializer = BookSerializer(
book,
fields=['id', 'title', 'price', 'author'],
rename_fields={
'price': 'retail_price',
'id': 'book_id'
},
nested={
'author': {
'serializer': AuthorSerializer,
'fields': ['id', 'bio', 'user'],
'rename_fields': {'bio': 'biography'},
'nested': {
'user': {
'serializer': UserSerializer,
'fields': ['id','username', 'email'],
}
}
}
}
)
return Response(serializer.data)
Feature Highlights
1. Field Selection
The fields parameter lets you cherry-pick exactly which fields to include in the output
AuthorSerializer(
author,
fields=['id', 'name', 'birth_date']
)
2. Field Attributes
Pass the standard DRF serializers params in run-time
AuthorSerializer(
author,
field_attributes={
'bio': {'help_text': 'Author biography'}
}
)
3. Field Renaming
rename_fields allows you to customize the output keys without changing your models.
BookSerializer(
book,
rename_fields={
'price': 'retail_price', # Output will show 'retail_price' instead of 'price'
'id': 'book_id'
}
)
4. Nested Relationships
The nested serializer configuration provides ultimate flexibility for relationships. You can define unlimited nesting levels while maintaining full control over each level's behavior. The configuration supports all standard DRF parameters such as read_only or instance alongside this package-specific features, allowing you to mix and match functionality as needed. Each nested serializer can itself be configured with fields selection, renaming, and even deeper nesting - creating truly dynamic relationship trees that adapt to your API requirements.
AuthorSerializer(
author,
nested={
'books': {
'serializer': BookSerializer,
'fields': ['title', 'publish_year'],
'nested': {
'publisher': {
'serializer': PublisherSerializer,
'fields': ['name', 'country']
}
}
}
}
)
For complex nested structures, you can build and config relationships as deep as your API requires:
آ serializer = DynamicBlogPostSerializer(
آ آ آ آ آ آ self.post1,
آ آ آ آ آ آ fields=["id", "title", "author", "comments"],
آ آ آ آ آ آ rename_fields={"id": "post_identifier"},
آ آ آ آ آ آ nested={
آ آ آ آ آ آ آ آ "author": {
آ آ آ آ آ آ آ آ آ آ "serializer": DynamicAuthorProfileSerializer,
آ آ آ آ آ آ آ آ آ آ "fields": ["bio", "is_verified"],
آ آ آ آ آ آ آ آ آ آ "rename_fields": {"bio": "author_biography"},
آ آ آ آ آ آ آ آ آ آ "field_attributes": {
آ آ آ آ آ آ آ آ آ آ آ آ "is_verified": {"help_text": "Verified status"}
آ آ آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ آ آ "nested": {
آ آ آ آ آ آ آ آ آ آ آ آ "user": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "serializer": UserSerializer,
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "fields": ["id", "username"],
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "rename_fields": {"username": "user_login"},
آ آ آ آ آ آ آ آ آ آ آ آ }
آ آ آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ "comments": {
آ آ آ آ آ آ آ آ آ آ "serializer": DynamicCommentSerializer,
آ آ آ آ آ آ آ آ آ آ "fields": ["id", "content", "user", "replies"],
آ آ آ آ آ آ آ آ آ آ "instance": self.post1.comments.filter(
آ آ آ آ آ آ آ آ آ آ آ آ is_approved=True, parent__isnull=True
آ آ آ آ آ آ آ آ آ آ ),
آ آ آ آ آ آ آ آ آ آ "rename_fields": {"content": "comment_text"},
آ آ آ آ آ آ آ آ آ آ "field_attributes": {"id": {"label": "Comment ID"}},
آ آ آ آ آ آ آ آ آ آ "nested": {
آ آ آ آ آ آ آ آ آ آ آ آ "user": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "serializer": UserSerializer,
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "fields": ["id", "username"],
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "rename_fields": {"username": "commenter_name"},
آ آ آ آ آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ آ آ آ آ "replies": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "serializer": DynamicCommentSerializer,
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "fields": ["id", "content", "user"],
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "instance": lambda instance, ctx: instance.replies.filter(is_approved=True)
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "rename_fields": {"content": "reply_text"},
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "field_attributes": {"id": {"label": "Reply ID"}},
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "nested": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "user": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "serializer": UserSerializer,
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "fields": ["id", "username"],
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "rename_fields": {"username": "replier_name"},
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ }
آ آ آ آ آ آ آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ },
آ آ آ آ )
even the very complex and deep relations are supported:
serializer = DynamicBlogPostSerializer(
آ آ آ آ آ آ self.post,
آ آ آ آ آ آ fields=["id", "title", "author", "tags", "comments", "likes"],
آ آ آ آ آ آ nested={
آ آ آ آ آ آ آ آ "author": {
آ آ آ آ آ آ آ آ آ آ "serializer": DynamicAuthorProfileSerializer,
آ آ آ آ آ آ آ آ آ آ "fields": ["id", "bio", "user"],
آ آ آ آ آ آ آ آ آ آ "nested": {
آ آ آ آ آ آ آ آ آ آ آ آ "user": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "serializer": UserSerializer,
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "fields": [
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "id",
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "email",
آ آ آ آ آ آ آ آ آ آ آ آ آ آ ],
آ آ آ آ آ آ آ آ آ آ آ آ آ آ "nested": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "author_profile": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "serializer": DynamicAuthorProfileSerializer,
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "fields": ["bio"],
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "nested": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "blog_posts": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "serializer":DynamicBlogPostSerializer,
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "fields": ["title"],
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "nested": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "tags": {
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "serializer": TagSerializer,
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "fields": ["name"],
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ "many":True,
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ }
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ }
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ آ }
آ آ آ آ آ آ آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ آ آ آ آ }
آ آ آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ آ },
آ آ آ آ آ آ آ )
5. Conditional Fields
Choose the fields that will appear based on conditions easily:
AuthorSerializer(
author,
conditional_fields={
'email': lambda instance, ctx: ctx['request'].user.is_staff
}
)
WHEN TO USE
- Building public APIs with multiple versions
- Projects needing different views of the same data
- Rapidly evolving API requirements
- Any Django REST Framework project tired of serializer bloat
Contributing
We welcome contributions! please check the CONTRIBUTING.md file
License
This project is licensed under the MIT License. See the LICENSE file for details.
Acknowledgements
Inspired by the flexibility needs of complex API systems. Special thanks to the Django REST Framework community for their foundational work .
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 drf_shapeless_serializers-1.0.2.tar.gz.
File metadata
- Download URL: drf_shapeless_serializers-1.0.2.tar.gz
- Upload date:
- Size: 5.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4b14e8bf293b297b5f703f9e11fa8863a41b7636c7642634c2cd99d6a786ae1
|
|
| MD5 |
17c134d4ca66819ea84d082ba903468a
|
|
| BLAKE2b-256 |
64d3d9299a92f4fc799e27c3046b268878979b83dace2e8ab9fd6c457d3d7007
|
File details
Details for the file drf_shapeless_serializers-1.0.2-py3-none-any.whl.
File metadata
- Download URL: drf_shapeless_serializers-1.0.2-py3-none-any.whl
- Upload date:
- Size: 4.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a844500c70cd98f3fade74af33b70117ea7334c8d698a3ee10a3b07c948cefed
|
|
| MD5 |
38a642531bdb37247ccc0d232bfac200
|
|
| BLAKE2b-256 |
e9d3204b64df4b951525ce6d020ff0a9e290f099015449ead33faf059cea2fa2
|