django-ninja-aio-crud 2.3.2__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of django-ninja-aio-crud might be problematic. Click here for more details.
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/PKG-INFO +29 -1
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/README.md +28 -0
- django_ninja_aio_crud-2.4.0/docs/api/models/serializers.md +130 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/index.md +35 -12
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/mkdocs.yml +1 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/__init__.py +1 -1
- django_ninja_aio_crud-2.4.0/ninja_aio/models/__init__.py +4 -0
- django_ninja_aio_crud-2.4.0/ninja_aio/models/serializers.py +738 -0
- django_ninja_aio_crud-2.3.2/ninja_aio/models.py → django_ninja_aio_crud-2.4.0/ninja_aio/models/utils.py +19 -662
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/views/api.py +26 -9
- django_ninja_aio_crud-2.4.0/tests/test_app/serializers.py +31 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/test_app/views.py +16 -2
- django_ninja_aio_crud-2.4.0/tests/test_serializers.py +106 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/test_settings.py +2 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/views/test_viewset.py +36 -2
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/.github/dependabot.yml +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/.github/workflows/coverage.yml +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/.github/workflows/docs.yml +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/.github/workflows/publish.yml +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/.gitignore +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/.pre-commit-config.yaml +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/LICENSE +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/CNAME +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/api/authentication.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/api/models/model_serializer.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/api/models/model_util.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/api/pagination.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/api/renderers/orjson_renderer.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/api/views/api_view.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/api/views/api_view_set.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/api/views/decorators.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/api/views/mixins.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/auth.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/contributing.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/extra.css +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/getting_started/images/index/foo-index-create-swagger.png +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/getting_started/images/index/foo-index-delete-swagger.png +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/getting_started/images/index/foo-index-list-swagger.png +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/getting_started/images/index/foo-index-retrieve-swagger.png +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/getting_started/images/index/foo-index-swagger.png +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/getting_started/images/index/foo-index-update-swagger.png +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/getting_started/installation.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/getting_started/quick_start.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/images/bar-swagger.png +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/images/favicon.ico +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/images/foo-swagger.png +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/images/logo.png +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/images/model_util/foo-reverse-relations-swagger.png +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/release_notes.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/requirements.txt +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/tutorial/authentication.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/tutorial/crud.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/tutorial/filtering.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/docs/tutorial/model.md +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/main.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/api.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/auth.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/decorators/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/decorators/operations.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/decorators/views.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/exceptions.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/factory/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/factory/operations.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/helpers/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/helpers/api.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/helpers/query.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/parsers.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/renders.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/schemas/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/schemas/api.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/schemas/generics.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/schemas/helpers.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/types.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/views/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/ninja_aio/views/mixins.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/pyproject.toml +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/requirements.dev.txt +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/run-local-coverage.sh +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/core/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/core/test_decorators.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/core/test_exceptions_api.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/core/test_renderer_parser.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/generics/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/generics/literals.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/generics/models.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/generics/request.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/generics/views.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/helpers/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/helpers/test_many_to_many_api.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/models/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/models/test_model_util.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/models/test_models_extra.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/test_app/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/test_app/models.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/test_app/schema.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/test_auth.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/test_decorators.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/test_exceptions.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/test_query_util.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/views/__init__.py +0 -0
- {django_ninja_aio_crud-2.3.2 → django_ninja_aio_crud-2.4.0}/tests/views/test_views.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-ninja-aio-crud
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: Django Ninja AIO CRUD - Rest Framework
|
|
5
5
|
Author: Giuseppe Casillo
|
|
6
6
|
Requires-Python: >=3.10, <3.15
|
|
@@ -262,6 +262,34 @@ class BookViewSet(APIViewSet):
|
|
|
262
262
|
|
|
263
263
|
---
|
|
264
264
|
|
|
265
|
+
## Meta-driven Serializer (for vanilla Django models)
|
|
266
|
+
|
|
267
|
+
If you already have Django models and don't want to inherit from ModelSerializer, use the Meta-driven Serializer to generate dynamic schemas and integrate with APIViewSet.
|
|
268
|
+
|
|
269
|
+
Example:
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
from ninja_aio.models import serializers
|
|
273
|
+
from . import models
|
|
274
|
+
|
|
275
|
+
class BookSerializer(serializers.Serializer):
|
|
276
|
+
class Meta:
|
|
277
|
+
model = models.Book
|
|
278
|
+
schema_in = serializers.SchemaModelConfig(fields=["title", "published"])
|
|
279
|
+
schema_out = serializers.SchemaModelConfig(fields=["id", "title", "published"])
|
|
280
|
+
schema_update = serializers.SchemaModelConfig(optionals=[("title", str), ("published", bool)])
|
|
281
|
+
|
|
282
|
+
@api.viewset(models.Book)
|
|
283
|
+
class BookViewSet(APIViewSet):
|
|
284
|
+
serializer_class = BookSerializer
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
- Works without modifying existing models
|
|
288
|
+
- Supports nested relations via relations_serializers
|
|
289
|
+
- APIViewSet will auto-generate missing schemas from the serializer
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
265
293
|
## 🛠 Project Structure & Docs
|
|
266
294
|
|
|
267
295
|
Documentation (MkDocs + Material):
|
|
@@ -227,6 +227,34 @@ class BookViewSet(APIViewSet):
|
|
|
227
227
|
|
|
228
228
|
---
|
|
229
229
|
|
|
230
|
+
## Meta-driven Serializer (for vanilla Django models)
|
|
231
|
+
|
|
232
|
+
If you already have Django models and don't want to inherit from ModelSerializer, use the Meta-driven Serializer to generate dynamic schemas and integrate with APIViewSet.
|
|
233
|
+
|
|
234
|
+
Example:
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
from ninja_aio.models import serializers
|
|
238
|
+
from . import models
|
|
239
|
+
|
|
240
|
+
class BookSerializer(serializers.Serializer):
|
|
241
|
+
class Meta:
|
|
242
|
+
model = models.Book
|
|
243
|
+
schema_in = serializers.SchemaModelConfig(fields=["title", "published"])
|
|
244
|
+
schema_out = serializers.SchemaModelConfig(fields=["id", "title", "published"])
|
|
245
|
+
schema_update = serializers.SchemaModelConfig(optionals=[("title", str), ("published", bool)])
|
|
246
|
+
|
|
247
|
+
@api.viewset(models.Book)
|
|
248
|
+
class BookViewSet(APIViewSet):
|
|
249
|
+
serializer_class = BookSerializer
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
- Works without modifying existing models
|
|
253
|
+
- Supports nested relations via relations_serializers
|
|
254
|
+
- APIViewSet will auto-generate missing schemas from the serializer
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
230
258
|
## 🛠 Project Structure & Docs
|
|
231
259
|
|
|
232
260
|
Documentation (MkDocs + Material):
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Serializer (Meta-driven)
|
|
2
|
+
|
|
3
|
+
The Serializer class provides dynamic schema generation and relation handling for existing Django models without requiring you to adopt the ModelSerializer base class. Use it when:
|
|
4
|
+
|
|
5
|
+
- You already have vanilla Django models in a project and want dynamic Ninja schemas.
|
|
6
|
+
- You prefer to keep models unchanged and define serialization externally.
|
|
7
|
+
|
|
8
|
+
It mirrors the behavior of ModelSerializer but reads configuration from a nested Meta class.
|
|
9
|
+
|
|
10
|
+
## Key points
|
|
11
|
+
|
|
12
|
+
- Works with any Django model (no inheritance required).
|
|
13
|
+
- Generates read/create/update/related schemas on demand via ninja.orm.create_schema.
|
|
14
|
+
- Supports explicit relation serializers for forward and reverse relations.
|
|
15
|
+
- Plays nicely with APIViewSet to auto-wire schemas and queryset handling.
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
Define a Serializer subclass with a nested Meta:
|
|
20
|
+
|
|
21
|
+
- model: Django model class.
|
|
22
|
+
- schema_in: SchemaModelConfig for create inputs.
|
|
23
|
+
- schema_out: SchemaModelConfig for read outputs.
|
|
24
|
+
- schema_update: SchemaModelConfig for patch/update inputs.
|
|
25
|
+
- relations_serializers: mapping of relation field name -> Serializer to include nested schemas for relations.
|
|
26
|
+
|
|
27
|
+
SchemaModelConfig fields:
|
|
28
|
+
|
|
29
|
+
- fields: list[str]
|
|
30
|
+
- optionals: list[tuple[str, type]]
|
|
31
|
+
- exclude: list[str]
|
|
32
|
+
- customs: list[tuple[str, type, Any]]
|
|
33
|
+
|
|
34
|
+
## Example: simple FK
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from ninja_aio.models import serializers
|
|
38
|
+
from . import models
|
|
39
|
+
|
|
40
|
+
class ArticleSerializer(serializers.Serializer):
|
|
41
|
+
class Meta:
|
|
42
|
+
model = models.Article
|
|
43
|
+
schema_in = serializers.SchemaModelConfig(
|
|
44
|
+
fields=["title", "content", "author"]
|
|
45
|
+
)
|
|
46
|
+
schema_out = serializers.SchemaModelConfig(
|
|
47
|
+
fields=["id", "title", "content", "author"]
|
|
48
|
+
)
|
|
49
|
+
schema_update = serializers.SchemaModelConfig(
|
|
50
|
+
optionals=[("title", str), ("content", str)]
|
|
51
|
+
)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Generate schemas when needed:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
ArticleSerializer.generate_read_s()
|
|
58
|
+
ArticleSerializer.generate_create_s()
|
|
59
|
+
ArticleSerializer.generate_update_s()
|
|
60
|
+
ArticleSerializer.generate_related_s()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Example: reverse relation with nested serialization
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
class AuthorSerializer(serializers.Serializer):
|
|
67
|
+
class Meta:
|
|
68
|
+
model = models.Author
|
|
69
|
+
schema_out = serializers.SchemaModelConfig(
|
|
70
|
+
fields=["id", "name", "articles"] # reverse related name
|
|
71
|
+
)
|
|
72
|
+
relations_serializers = {
|
|
73
|
+
"articles": ArticleSerializer, # include nested article schema
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Notes:
|
|
78
|
+
|
|
79
|
+
- Forward relations are included as plain fields unless a related ModelSerializer/Serializer is declared.
|
|
80
|
+
- Reverse relations require an entry in relations_serializers when using vanilla Django models.
|
|
81
|
+
- When the related model is a ModelSerializer, related schemas can be auto-resolved.
|
|
82
|
+
|
|
83
|
+
## Using with APIViewSet
|
|
84
|
+
|
|
85
|
+
You can attach a Serializer to an APIViewSet to auto-generate schemas and leverage queryset_request when present:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from ninja_aio.views import APIViewSet
|
|
89
|
+
from ninja_aio import NinjaAIO
|
|
90
|
+
from . import models
|
|
91
|
+
|
|
92
|
+
api = NinjaAIO()
|
|
93
|
+
|
|
94
|
+
@api.viewset(models.Article)
|
|
95
|
+
class ArticleViewSet(APIViewSet):
|
|
96
|
+
serializer_class = ArticleSerializer
|
|
97
|
+
# Optionally define query_params or custom handlers
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Behavior:
|
|
101
|
+
|
|
102
|
+
- If model is a ModelSerializer, APIViewSet uses the model to generate schemas.
|
|
103
|
+
- If model is a vanilla model and serializer_class is provided, APIViewSet uses the Serializer to generate missing schemas.
|
|
104
|
+
- ModelUtil uses serializer_class.queryset_request if defined to build optimized querysets.
|
|
105
|
+
|
|
106
|
+
## Advanced: customs and optionals
|
|
107
|
+
|
|
108
|
+
Customs and optionals behave like ModelSerializer:
|
|
109
|
+
|
|
110
|
+
- customs: synthetic fields included in schemas (with default or required when default is Ellipsis).
|
|
111
|
+
- optionals: patch-like optional fields. In read schema, they are included with default None.
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
class PublishSerializer(serializers.Serializer):
|
|
115
|
+
class Meta:
|
|
116
|
+
model = models.Article
|
|
117
|
+
schema_update = serializers.SchemaModelConfig(
|
|
118
|
+
optionals=[("is_published", bool)],
|
|
119
|
+
customs=[("notify_subscribers", bool, True)],
|
|
120
|
+
)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
generate_update_s merges optionals and customs for the Patch schema.
|
|
124
|
+
|
|
125
|
+
## When to choose Serializer vs ModelSerializer
|
|
126
|
+
|
|
127
|
+
- Serializer: Keep your existing models unchanged; define schemas near your API layer. Ideal for incremental adoption.
|
|
128
|
+
- ModelSerializer: Centralize API schema and hooks on the model class itself. Ideal for greenfield projects inside this framework.
|
|
129
|
+
|
|
130
|
+
Both approaches support nested relations and dynamic schema generation. Choose the one that best fits your project structure.
|
|
@@ -33,12 +33,11 @@ Traditional Django REST development requires:
|
|
|
33
33
|
**Django Ninja Aio CRUD** eliminates this complexity:
|
|
34
34
|
|
|
35
35
|
=== "Traditional Approach"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
fields = ['id', 'username', 'email']
|
|
36
|
+
```python # schema.py
|
|
37
|
+
class UserSchemaOut(ModelSchema)
|
|
38
|
+
class Meta:
|
|
39
|
+
model = User
|
|
40
|
+
fields = ['id', 'username', 'email']
|
|
42
41
|
|
|
43
42
|
class UserSchemaIn(ModelSchema):
|
|
44
43
|
class Meta:
|
|
@@ -60,12 +59,11 @@ Traditional Django REST development requires:
|
|
|
60
59
|
```
|
|
61
60
|
|
|
62
61
|
=== "Django Ninja Aio CRUD"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
password = models.CharField(max_length=128)
|
|
62
|
+
```python # models.py
|
|
63
|
+
class User(ModelSerializer):
|
|
64
|
+
username = models.CharField(max_length=150)
|
|
65
|
+
email = models.EmailField()
|
|
66
|
+
password = models.CharField(max_length=128)
|
|
69
67
|
|
|
70
68
|
class ReadSerializer:
|
|
71
69
|
fields = ["id", "username", "email"]
|
|
@@ -92,6 +90,7 @@ Explore detailed documentation for each component:
|
|
|
92
90
|
|
|
93
91
|
- **[Model Serializer](api/models/model_serializer.md)** - Schema generation and serialization
|
|
94
92
|
- **[Model Util](api/models/model_util.md)** - Async CRUD utilities
|
|
93
|
+
- **[Serializer (Meta-driven)](api/models/serializers.md)** - Dynamic schemas for existing Django models without inheriting ModelSerializer
|
|
95
94
|
|
|
96
95
|
#### Views
|
|
97
96
|
|
|
@@ -273,6 +272,30 @@ class User(ModelSerializer):
|
|
|
273
272
|
optionals = [("username", str)] # Partial update schema
|
|
274
273
|
```
|
|
275
274
|
|
|
275
|
+
### Serializer (Meta-driven)
|
|
276
|
+
|
|
277
|
+
Use when you have vanilla Django models and want dynamic serialization without changing your model base class.
|
|
278
|
+
|
|
279
|
+
```python
|
|
280
|
+
from ninja_aio.models import serializers
|
|
281
|
+
from . import models
|
|
282
|
+
|
|
283
|
+
class BookSerializer(serializers.Serializer):
|
|
284
|
+
class Meta:
|
|
285
|
+
model = models.Book
|
|
286
|
+
schema_in = serializers.SchemaModelConfig(fields=["title", "published"])
|
|
287
|
+
schema_out = serializers.SchemaModelConfig(fields=["id", "title", "published"])
|
|
288
|
+
schema_update = serializers.SchemaModelConfig(optionals=[("title", str), ("published", bool)])
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Attach to an APIViewSet:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
@api.viewset(models.Book)
|
|
295
|
+
class BookViewSet(APIViewSet):
|
|
296
|
+
serializer_class = BookSerializer
|
|
297
|
+
```
|
|
298
|
+
|
|
276
299
|
### APIViewSet
|
|
277
300
|
|
|
278
301
|
Automatically generates complete CRUD endpoints:
|
|
@@ -24,6 +24,7 @@ nav:
|
|
|
24
24
|
- Models:
|
|
25
25
|
- ModelSerializer: api/models/model_serializer.md
|
|
26
26
|
- ModelUtil: api/models/model_util.md
|
|
27
|
+
- Serializer (Meta-driven): api/models/serializers.md
|
|
27
28
|
- Authentication: api/authentication.md
|
|
28
29
|
- Pagination: api/pagination.md
|
|
29
30
|
- Authentication:
|