django-ninja-aio-crud 0.7.8__tar.gz → 0.8.1__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.
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/PKG-INFO +8 -2
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/README.md +7 -1
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/ninja_aio/__init__.py +1 -1
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/ninja_aio/models.py +54 -5
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/ninja_aio/renders.py +11 -3
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/ninja_aio/views.py +2 -2
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/LICENSE +0 -0
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/ninja_aio/api.py +0 -0
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/ninja_aio/auth.py +0 -0
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/ninja_aio/exceptions.py +0 -0
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/ninja_aio/parsers.py +0 -0
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/ninja_aio/schemas.py +0 -0
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/ninja_aio/types.py +0 -0
- {django_ninja_aio_crud-0.7.8 → django_ninja_aio_crud-0.8.1}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-ninja-aio-crud
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.1
|
|
4
4
|
Summary: Django Ninja AIO CRUD - Rest Framework
|
|
5
5
|
Author: Giuseppe Casillo
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -138,7 +138,7 @@ class Foo(ModelSerializer):
|
|
|
138
138
|
|
|
139
139
|
- post create method is a custom method that comes out to handle actions which will be excuted after that the object is created. It can be used, indeed, for example to handle custom fields' actions.
|
|
140
140
|
|
|
141
|
-
- You can also define optional fields for you Create and Update serializers
|
|
141
|
+
- You can also define optional fields for you Create and Update serializers. To declare an optional fields you have to give the field type too.
|
|
142
142
|
```python
|
|
143
143
|
# models.py
|
|
144
144
|
from django.db import models
|
|
@@ -213,7 +213,13 @@ class Foo(ModelSerializer):
|
|
|
213
213
|
excludes = ["id", "name"]
|
|
214
214
|
optionals = [("bar", str), ("active", bool)]
|
|
215
215
|
```
|
|
216
|
+
- ModelSerializer comes out also with methods executed on object save and delete, them are:
|
|
216
217
|
|
|
218
|
+
1. on_create_before_save: code executed on object creation but before saving;
|
|
219
|
+
1. on_create_after_save: code executed on object creation but after saving;
|
|
220
|
+
1. before_save: code executed on every save but before saving;
|
|
221
|
+
1. after_save: code executed on every save but after saving;
|
|
222
|
+
1. on_delete: code executed after object delete;
|
|
217
223
|
|
|
218
224
|
|
|
219
225
|
### APIViewSet
|
|
@@ -106,7 +106,7 @@ class Foo(ModelSerializer):
|
|
|
106
106
|
|
|
107
107
|
- post create method is a custom method that comes out to handle actions which will be excuted after that the object is created. It can be used, indeed, for example to handle custom fields' actions.
|
|
108
108
|
|
|
109
|
-
- You can also define optional fields for you Create and Update serializers
|
|
109
|
+
- You can also define optional fields for you Create and Update serializers. To declare an optional fields you have to give the field type too.
|
|
110
110
|
```python
|
|
111
111
|
# models.py
|
|
112
112
|
from django.db import models
|
|
@@ -181,7 +181,13 @@ class Foo(ModelSerializer):
|
|
|
181
181
|
excludes = ["id", "name"]
|
|
182
182
|
optionals = [("bar", str), ("active", bool)]
|
|
183
183
|
```
|
|
184
|
+
- ModelSerializer comes out also with methods executed on object save and delete, them are:
|
|
184
185
|
|
|
186
|
+
1. on_create_before_save: code executed on object creation but before saving;
|
|
187
|
+
1. on_create_after_save: code executed on object creation but after saving;
|
|
188
|
+
1. before_save: code executed on every save but before saving;
|
|
189
|
+
1. after_save: code executed on every save but after saving;
|
|
190
|
+
1. on_delete: code executed after object delete;
|
|
185
191
|
|
|
186
192
|
|
|
187
193
|
### APIViewSet
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import base64
|
|
2
3
|
from typing import Any
|
|
3
4
|
|
|
@@ -94,7 +95,7 @@ class ModelUtil:
|
|
|
94
95
|
return reverse_rels
|
|
95
96
|
|
|
96
97
|
async def parse_input_data(self, request: HttpRequest, data: Schema):
|
|
97
|
-
payload = data.model_dump()
|
|
98
|
+
payload = data.model_dump(mode="json")
|
|
98
99
|
customs = {}
|
|
99
100
|
optionals = []
|
|
100
101
|
if isinstance(self.model, ModelSerializerMeta):
|
|
@@ -127,7 +128,7 @@ class ModelUtil:
|
|
|
127
128
|
|
|
128
129
|
async def parse_output_data(self, request: HttpRequest, data: Schema):
|
|
129
130
|
olds_k: list[dict] = []
|
|
130
|
-
payload = data.model_dump()
|
|
131
|
+
payload = data.model_dump(mode="json")
|
|
131
132
|
for k, v in payload.items():
|
|
132
133
|
try:
|
|
133
134
|
field_obj = (await agetattr(self.model, k)).field
|
|
@@ -142,7 +143,7 @@ class ModelUtil:
|
|
|
142
143
|
):
|
|
143
144
|
rel_util = ModelUtil(field_obj.related_model)
|
|
144
145
|
rel: ModelSerializer = await rel_util.get_object(
|
|
145
|
-
request,
|
|
146
|
+
request, v.get(rel_util.model_pk_name)
|
|
146
147
|
)
|
|
147
148
|
if isinstance(field_obj, models.ForeignKey):
|
|
148
149
|
for rel_k, rel_v in v.items():
|
|
@@ -162,8 +163,7 @@ class ModelUtil:
|
|
|
162
163
|
pk = (await self.model.objects.acreate(**payload)).pk
|
|
163
164
|
obj = await self.get_object(request, pk)
|
|
164
165
|
if isinstance(self.model, ModelSerializerMeta):
|
|
165
|
-
await obj.custom_actions(customs)
|
|
166
|
-
await obj.post_create()
|
|
166
|
+
await asyncio.gather(obj.custom_actions(customs), obj.post_create())
|
|
167
167
|
return await self.read_s(request, obj, obj_schema)
|
|
168
168
|
|
|
169
169
|
async def read_s(
|
|
@@ -491,3 +491,52 @@ class ModelSerializer(models.Model, metaclass=ModelSerializerMeta):
|
|
|
491
491
|
@classmethod
|
|
492
492
|
def generate_related_s(cls) -> Schema:
|
|
493
493
|
return cls._generate_model_schema("Related")
|
|
494
|
+
|
|
495
|
+
def after_save(self):
|
|
496
|
+
"""
|
|
497
|
+
Override this method to execute code after the object
|
|
498
|
+
has been saved
|
|
499
|
+
"""
|
|
500
|
+
pass
|
|
501
|
+
|
|
502
|
+
def before_save(self):
|
|
503
|
+
"""
|
|
504
|
+
Override this method to execute code before the object
|
|
505
|
+
has been saved
|
|
506
|
+
"""
|
|
507
|
+
pass
|
|
508
|
+
|
|
509
|
+
def on_create_after_save(self):
|
|
510
|
+
"""
|
|
511
|
+
Override this method to execute code after the object
|
|
512
|
+
has been created
|
|
513
|
+
"""
|
|
514
|
+
pass
|
|
515
|
+
|
|
516
|
+
def on_create_before_save(self):
|
|
517
|
+
"""
|
|
518
|
+
Override this method to execute code before the object
|
|
519
|
+
has been created
|
|
520
|
+
"""
|
|
521
|
+
pass
|
|
522
|
+
|
|
523
|
+
def on_delete(self):
|
|
524
|
+
"""
|
|
525
|
+
Override this method to execute code after the object
|
|
526
|
+
has been deleted
|
|
527
|
+
"""
|
|
528
|
+
pass
|
|
529
|
+
|
|
530
|
+
def save(self, *args, **kwargs):
|
|
531
|
+
if self._state.adding:
|
|
532
|
+
self.on_create_before_save()
|
|
533
|
+
self.before_save()
|
|
534
|
+
super().save(*args, **kwargs)
|
|
535
|
+
if self._state.adding:
|
|
536
|
+
self.on_create_after_save()
|
|
537
|
+
self.after_save()
|
|
538
|
+
|
|
539
|
+
def delete(self, *args, **kwargs):
|
|
540
|
+
res = super().delete(*args, **kwargs)
|
|
541
|
+
self.on_delete()
|
|
542
|
+
return res
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import base64
|
|
2
|
+
from ipaddress import IPv4Address, IPv6Address
|
|
2
3
|
|
|
3
4
|
import orjson
|
|
4
5
|
from django.http import HttpRequest
|
|
@@ -31,16 +32,23 @@ class ORJSONRenderer(BaseRenderer):
|
|
|
31
32
|
for k, v in data.items():
|
|
32
33
|
if isinstance(v, bytes):
|
|
33
34
|
data |= {k: base64.b64encode(v).decode()}
|
|
35
|
+
continue
|
|
36
|
+
if isinstance(v, (IPv4Address, IPv6Address)):
|
|
37
|
+
data |= {k: str(v)}
|
|
38
|
+
continue
|
|
34
39
|
if isinstance(v, dict):
|
|
35
40
|
for k_rel, v_rel in v.items():
|
|
36
|
-
if
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
if isinstance(v_rel, bytes):
|
|
42
|
+
v |= {k_rel: base64.b64encode(v_rel).decode()}
|
|
43
|
+
if isinstance(v_rel, (IPv4Address, IPv6Address)):
|
|
44
|
+
v |= {k_rel: str(v_rel)}
|
|
39
45
|
data |= {k: v}
|
|
40
46
|
if isinstance(v, list):
|
|
41
47
|
for index_rel, f_rel in enumerate(v):
|
|
42
48
|
for k_rel, v_rel in f_rel.items():
|
|
43
49
|
if isinstance(v_rel, bytes):
|
|
44
50
|
v[index_rel] |= {k_rel: base64.b64encode(v_rel).decode()}
|
|
51
|
+
if isinstance(v_rel, (IPv4Address, IPv6Address)):
|
|
52
|
+
v[index_rel] |= {k_rel: str(v_rel)}
|
|
45
53
|
data |= {k: v}
|
|
46
54
|
return data
|
|
@@ -46,7 +46,7 @@ class APIView:
|
|
|
46
46
|
|
|
47
47
|
AUTHENTICATED VIEW:
|
|
48
48
|
|
|
49
|
-
@self.router.get(some_path, response=some_schema, auth=self.
|
|
49
|
+
@self.router.get(some_path, response=some_schema, auth=self.auth)
|
|
50
50
|
async def some_method(request, *args, **kwargs):
|
|
51
51
|
pass
|
|
52
52
|
|
|
@@ -243,7 +243,7 @@ class APIViewSet:
|
|
|
243
243
|
|
|
244
244
|
AUTHENTICATED VIEW:
|
|
245
245
|
|
|
246
|
-
@self.router.get(some_path, response=some_schema, auth=self.
|
|
246
|
+
@self.router.get(some_path, response=some_schema, auth=self.auth)
|
|
247
247
|
async def some_method(request, *args, **kwargs):
|
|
248
248
|
pass
|
|
249
249
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|