drf-shapeless-serializers


Namedrf-shapeless-serializers JSON
Version 1.0.6 PyPI version JSON
download
home_pageNone
SummaryDynamic 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.
upload_time2025-07-19 22:02:17
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT
keywords django django-rest-framework drf serializers api dynamic runtime configuration nested relationships rest json apis
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
# drf-shapeless-serializers 
[![Published on Django Packages](https://img.shields.io/badge/Published%20on-Django%20Packages-0c3c26)](https://djangopackages.org/packages/p/drf-shapeless-serializers/)

## Motivation
Traditional Django REST Framework serializers often lead to what’s known as “serializer hell” - a situation where developers:

- Create numerous serializer variations for slightly different API endpoints
- Duplicate code for simple field variations
- Struggle with rigid and complex nested relationships
- Maintain sprawling serializer classes that become hard to manage

`drf-shapeless-serializers` was created to solve these pain points by introducing dynamic runtime configuration capabilities, allowing you to eliminate up to 80% of your serializer code while gaining unprecedented flexibility.

## Documentation
https://drf-shapeless-serializers.readthedocs.io/en/latest/

## 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

```bash
pip install drf-shapeless-serializers
```

**Add to your Django settings**:
```python
INSTALLED_APPS = [
    # ... other apps
    'shapeless_serializers',
]
```

## Usage

### Basic Setup

1. **Define your shapeless serializer**:
```python
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__'
```

2. **Configure dynamically in views**:
```python
@api_view(['GET'])
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

```python
AuthorSerializer(
    author,
    fields=['id', 'name', 'birth_date']
)
```

#### 2. Field Attributes
Pass the standard DRF serializers params in run-time

```python
AuthorSerializer(
    author,
    field_attributes={
        'bio': {'help_text': 'Author biography'},
        'address' : {'write_only' : True }
    }
)
```

#### 3. Field Renaming
`rename_fields` allows you to customize the output keys without changing your models.

```python
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.

```python
AuthorSerializer(
    author,
    nested={
        'books': {
            'serializer': BookSerializer,
            'fields': ['title', 'publish_year', 'publisher'],
            'nested': {
                'publisher': {
                    'serializer': PublisherSerializer,
                    'fields': ['name', 'country']
                }
            }
        }
    }
)
```

For complex nested structures, you can build and config relationships as deep as your API requires:

```python
 posts = BlogPost.objects.all()
 serializer = DynamicBlogPostSerializer(
           posts,
            fields=["id", "title", "author", "comments"],
            rename_fields={"id": "post_identifier"},
            nested={
                "author": {
                    "serializer": DynamicAuthorProfileSerializer,
                    "fields": ["bio", "is_verified", 'user'],
                    "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": posts.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:
```python
posts =  BlogPost.objects.all()
serializer = DynamicBlogPostSerializer(
            posts,
            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:

```python
AuthorSerializer(
    author,
    conditional_fields={
        'email': lambda instance, ctx: ctx['request'].user.is_staff
    }
)
```

#### 6. Inline Shapeless Model Serializers
Create serializers on-the-fly without defining a serializer class, perfect for one-off serialization needs:

```python
book = Book.objects.get(pk=1)

serializer = InlineShapelessModelSerializer(
    book,
    model=Book,
    fields=['title', 'author', 'price'],
    nested={
        'author': {
            'serializer': InlineShapelessModelSerializer,
            'model': Author,
            'fields': ['name', 'bio']
        }
    }
)
```

## 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 .

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "drf-shapeless-serializers",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "django, django-rest-framework, drf, serializers, api, dynamic, runtime, configuration, nested, relationships, rest, json, APIs",
    "author": null,
    "author_email": "Khaled Sukkar <khaled.sukkar.contact@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/74/75/0fdcb0e71b51dd5e58cf0a69287113be8cb2c372f739231e95a80fc686c4/drf_shapeless_serializers-1.0.6.tar.gz",
    "platform": null,
    "description": "\r\n# drf-shapeless-serializers \r\n[![Published on Django Packages](https://img.shields.io/badge/Published%20on-Django%20Packages-0c3c26)](https://djangopackages.org/packages/p/drf-shapeless-serializers/)\r\n\r\n## Motivation\r\nTraditional Django REST Framework serializers often lead to what\u2019s known as \u201cserializer hell\u201d - a situation where developers:\r\n\r\n- Create numerous serializer variations for slightly different API endpoints\r\n- Duplicate code for simple field variations\r\n- Struggle with rigid and complex nested relationships\r\n- Maintain sprawling serializer classes that become hard to manage\r\n\r\n`drf-shapeless-serializers` was created to solve these pain points by introducing dynamic runtime configuration capabilities, allowing you to eliminate up to 80% of your serializer code while gaining unprecedented flexibility.\r\n\r\n## Documentation\r\nhttps://drf-shapeless-serializers.readthedocs.io/en/latest/\r\n\r\n## Overview\r\n\r\n`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.\r\nAll without creating multiple serializer classes and annoying nested relations. \r\n\r\n## Installation\r\n\r\n```bash\r\npip install drf-shapeless-serializers\r\n```\r\n\r\n**Add to your Django settings**:\r\n```python\r\nINSTALLED_APPS = [\r\n    # ... other apps\r\n    'shapeless_serializers',\r\n]\r\n```\r\n\r\n## Usage\r\n\r\n### Basic Setup\r\n\r\n1. **Define your shapeless serializer**:\r\n```python\r\nfrom shapeless_serializers.serializers import ShapelessModelSerializer\r\n  \r\nclass UserSerializer(ShapelessModelSerializer):\r\n    class Meta:\r\n        model = User\r\n        fields = '__all__'\r\n\r\nclass AuthorSerializer(ShapelessModelSerializer):\r\n    class Meta:\r\n        model = Author\r\n        fields = '__all__'\r\n\r\nclass BookSerializer(ShapelessModelSerializer):\r\n    class Meta:\r\n        model = Book\r\n        fields = '__all__'\r\n```\r\n\r\n2. **Configure dynamically in views**:\r\n```python\r\n@api_view(['GET'])\r\ndef book_detail(request, pk):\r\n    book = Book.objects.get(pk=pk)\r\n    serializer = BookSerializer(\r\n        book,\r\n        fields=['id', 'title', 'price', 'author'],\r\n        rename_fields={\r\n            'price': 'retail_price',\r\n            'id': 'book_id'\r\n        },\r\n        nested={\r\n            'author': {\r\n                'serializer': AuthorSerializer,\r\n                'fields': ['id', 'bio', 'user'],\r\n                'rename_fields': {'bio': 'biography'},\r\n                'nested': {\r\n                    'user': {\r\n                        'serializer': UserSerializer,\r\n                        'fields': ['id','username', 'email'],\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    )\r\n    return Response(serializer.data)\r\n```\r\n\r\n### Feature Highlights\r\n\r\n#### 1. Field Selection\r\nThe `fields` parameter lets you cherry-pick exactly which fields to include in the output\r\n\r\n```python\r\nAuthorSerializer(\r\n    author,\r\n    fields=['id', 'name', 'birth_date']\r\n)\r\n```\r\n\r\n#### 2. Field Attributes\r\nPass the standard DRF serializers params in run-time\r\n\r\n```python\r\nAuthorSerializer(\r\n    author,\r\n    field_attributes={\r\n        'bio': {'help_text': 'Author biography'},\r\n        'address' : {'write_only' : True }\r\n    }\r\n)\r\n```\r\n\r\n#### 3. Field Renaming\r\n`rename_fields` allows you to customize the output keys without changing your models.\r\n\r\n```python\r\nBookSerializer(\r\n    book,\r\n    rename_fields={\r\n        'price': 'retail_price',  # Output will show 'retail_price' instead of 'price'\r\n        'id': 'book_id'\r\n    }\r\n)\r\n```\r\n\r\n#### 4. Nested Relationships\r\nThe 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.\r\n\r\n```python\r\nAuthorSerializer(\r\n    author,\r\n    nested={\r\n        'books': {\r\n            'serializer': BookSerializer,\r\n            'fields': ['title', 'publish_year', 'publisher'],\r\n            'nested': {\r\n                'publisher': {\r\n                    'serializer': PublisherSerializer,\r\n                    'fields': ['name', 'country']\r\n                }\r\n            }\r\n        }\r\n    }\r\n)\r\n```\r\n\r\nFor complex nested structures, you can build and config relationships as deep as your API requires:\r\n\r\n```python\r\n posts = BlogPost.objects.all()\r\n\u00a0serializer = DynamicBlogPostSerializer(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0posts,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 fields=[\"id\", \"title\", \"author\", \"comments\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 rename_fields={\"id\": \"post_identifier\"},\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 nested={\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"author\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\": DynamicAuthorProfileSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\"bio\", \"is_verified\", 'user'],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"rename_fields\": {\"bio\": \"author_biography\"},\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"field_attributes\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"is_verified\": {\"help_text\": \"Verified status\"}\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"nested\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"user\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\": UserSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\"id\", \"username\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"rename_fields\": {\"username\": \"user_login\"},\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"comments\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\": DynamicCommentSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\"id\", \"content\", \"user\", \"replies\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"instance\": posts.comments.filter(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 is_approved=True, parent__isnull=True\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"rename_fields\": {\"content\": \"comment_text\"},\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"field_attributes\": {\"id\": {\"label\": \"Comment ID\"}},\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"nested\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"user\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\": UserSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\"id\", \"username\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"rename_fields\": {\"username\": \"commenter_name\"},\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"replies\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\": DynamicCommentSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\"id\", \"content\", \"user\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"instance\": lambda instance, ctx: instance.replies.filter(is_approved=True)\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"rename_fields\": {\"content\": \"reply_text\"},\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"field_attributes\": {\"id\": {\"label\": \"Reply ID\"}},\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"nested\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"user\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\": UserSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\"id\", \"username\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"rename_fields\": {\"username\": \"replier_name\"},\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 )\r\n```\r\n\r\neven the very complex and deep relations are supported:\r\n```python\r\nposts =  BlogPost.objects.all()\r\nserializer = DynamicBlogPostSerializer(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 posts,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 fields=[\"id\", \"title\", \"author\", \"tags\", \"comments\", \"likes\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 nested={\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"author\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\": DynamicAuthorProfileSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\"id\", \"bio\", \"user\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"nested\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"user\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\": UserSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"id\",\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"email\",\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"nested\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"author_profile\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\": DynamicAuthorProfileSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\"bio\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"nested\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"blog_posts\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\":DynamicBlogPostSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\"title\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"nested\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"tags\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"serializer\": TagSerializer,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"fields\": [\"name\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"many\":True,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n                    },\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0)\r\n```\r\n#### 5. Conditional Fields\r\nChoose the fields that will appear based on conditions easily:\r\n\r\n```python\r\nAuthorSerializer(\r\n    author,\r\n    conditional_fields={\r\n        'email': lambda instance, ctx: ctx['request'].user.is_staff\r\n    }\r\n)\r\n```\r\n\r\n#### 6. Inline Shapeless Model Serializers\r\nCreate serializers on-the-fly without defining a serializer class, perfect for one-off serialization needs:\r\n\r\n```python\r\nbook = Book.objects.get(pk=1)\r\n\r\nserializer = InlineShapelessModelSerializer(\r\n    book,\r\n    model=Book,\r\n    fields=['title', 'author', 'price'],\r\n    nested={\r\n        'author': {\r\n            'serializer': InlineShapelessModelSerializer,\r\n            'model': Author,\r\n            'fields': ['name', 'bio']\r\n        }\r\n    }\r\n)\r\n```\r\n\r\n## WHEN TO USE\r\n\r\n- Building public APIs with multiple versions  \r\n- Projects needing different views of the same data\r\n- Rapidly evolving API requirements  \r\n- Any Django REST Framework project tired of serializer bloat\r\n\r\n## Contributing\r\n\r\nWe welcome contributions! please check the `CONTRIBUTING.md` file\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License. See the LICENSE file for details.\r\n\r\n## Acknowledgements\r\n\r\nInspired by the flexibility needs of complex API systems. Special thanks to the Django REST Framework community for their foundational work .\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "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.",
    "version": "1.0.6",
    "project_urls": {
        "Documentation": "https://drf-shapeless-serializers.readthedocs.io/en/latest/",
        "Homepage": "https://github.com/khaledsukkar2/drf-shapeless-serializers"
    },
    "split_keywords": [
        "django",
        " django-rest-framework",
        " drf",
        " serializers",
        " api",
        " dynamic",
        " runtime",
        " configuration",
        " nested",
        " relationships",
        " rest",
        " json",
        " apis"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "932c44df9a60709acad0ff19662dd913d9a4c4107d299067270e3802e4905da6",
                "md5": "8b832f9b65be3a60adbcadb9d2731d7c",
                "sha256": "dd1d562c2a8ecf37c5a7da483648722dc2b45e666171d04141ca527a294e1682"
            },
            "downloads": -1,
            "filename": "drf_shapeless_serializers-1.0.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8b832f9b65be3a60adbcadb9d2731d7c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 8453,
            "upload_time": "2025-07-19T22:02:14",
            "upload_time_iso_8601": "2025-07-19T22:02:14.172615Z",
            "url": "https://files.pythonhosted.org/packages/93/2c/44df9a60709acad0ff19662dd913d9a4c4107d299067270e3802e4905da6/drf_shapeless_serializers-1.0.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "74750fdcb0e71b51dd5e58cf0a69287113be8cb2c372f739231e95a80fc686c4",
                "md5": "7a5b50986ed09a6acf18587ab5751ef9",
                "sha256": "26acdeeed6fb47eb06e2f7182d549c170f8c409954ac00c2bcc2d9e133bfa49c"
            },
            "downloads": -1,
            "filename": "drf_shapeless_serializers-1.0.6.tar.gz",
            "has_sig": false,
            "md5_digest": "7a5b50986ed09a6acf18587ab5751ef9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 8300,
            "upload_time": "2025-07-19T22:02:17",
            "upload_time_iso_8601": "2025-07-19T22:02:17.698105Z",
            "url": "https://files.pythonhosted.org/packages/74/75/0fdcb0e71b51dd5e58cf0a69287113be8cb2c372f739231e95a80fc686c4/drf_shapeless_serializers-1.0.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-19 22:02:17",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "khaledsukkar2",
    "github_project": "drf-shapeless-serializers",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "drf-shapeless-serializers"
}
        
Elapsed time: 1.38823s