django-ninja-aio-crud 0.8.3__tar.gz → 0.9.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.
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/PKG-INFO +1 -1
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/ninja_aio/__init__.py +1 -1
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/ninja_aio/views.py +89 -16
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/LICENSE +0 -0
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/README.md +0 -0
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/ninja_aio/api.py +0 -0
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/ninja_aio/auth.py +0 -0
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/ninja_aio/exceptions.py +0 -0
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/ninja_aio/models.py +0 -0
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/ninja_aio/parsers.py +0 -0
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/ninja_aio/renders.py +0 -0
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/ninja_aio/schemas.py +0 -0
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/ninja_aio/types.py +0 -0
- {django_ninja_aio_crud-0.8.3 → django_ninja_aio_crud-0.9.0}/pyproject.toml +0 -0
|
@@ -57,15 +57,67 @@ class APIView:
|
|
|
57
57
|
pass
|
|
58
58
|
"""
|
|
59
59
|
|
|
60
|
-
def
|
|
60
|
+
def _add_views(self):
|
|
61
61
|
self.views()
|
|
62
62
|
return self.router
|
|
63
63
|
|
|
64
64
|
def add_views_to_route(self):
|
|
65
|
-
return self.api.add_router(f"{self.api_route_path}
|
|
65
|
+
return self.api.add_router(f"{self.api_route_path}", self._add_views())
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
class APIViewSet:
|
|
69
|
+
"""
|
|
70
|
+
A base class for creating API views with CRUD operations.
|
|
71
|
+
|
|
72
|
+
This class provides methods for creating, listing, retrieving, updating,
|
|
73
|
+
and deleting objects of a specified model. It supports pagination,
|
|
74
|
+
authentication, and custom query parameters.
|
|
75
|
+
|
|
76
|
+
## Attributes:
|
|
77
|
+
- **model** (`ModelSerializer | Model`): The model for CRUD operations.
|
|
78
|
+
- **api** (`NinjaAPI`): The API instance to which the views are added.
|
|
79
|
+
- **schema_in** (`Schema | None`): Schema for input data in create/update operations.
|
|
80
|
+
- **schema_out** (`Schema | None`): Schema for output data in list/retrieve operations.
|
|
81
|
+
- **schema_update** (`Schema | None`): Schema for update operations.
|
|
82
|
+
- **auth** (`list | None`): Authentication classes for the views.
|
|
83
|
+
- **get_auth** (`list | None`): Authentication for GET requests.
|
|
84
|
+
- **post_auth** (`list | None`): Authentication for POST requests.
|
|
85
|
+
- **patch_auth** (`list | None`): Authentication for PATCH requests.
|
|
86
|
+
- **delete_auth** (`list | None`): Authentication for DELETE requests.
|
|
87
|
+
- **pagination_class** (`type[AsyncPaginationBase]`): Pagination class to use.
|
|
88
|
+
- **query_params** (`dict[str, tuple[type, ...]]`): Query parameters for filtering.
|
|
89
|
+
- **disable** (`list[type[VIEW_TYPES]]`): List of view types to disable.
|
|
90
|
+
- **api_route_path** (`str`): Base path for the API route.
|
|
91
|
+
- **list_docs** (`str`): Documentation for the list view.
|
|
92
|
+
- **create_docs** (`str`): Documentation for the create view.
|
|
93
|
+
- **retrieve_docs** (`str`): Documentation for the retrieve view.
|
|
94
|
+
- **update_docs** (`str`): Documentation for the update view.
|
|
95
|
+
- **delete_docs** (`str`): Documentation for the delete view.
|
|
96
|
+
|
|
97
|
+
## Notes:
|
|
98
|
+
If the model is a ModelSerializer instance, schemas are generated
|
|
99
|
+
automatically based on Create, Read, and Update serializers.
|
|
100
|
+
Override the `views` method to add custom views.
|
|
101
|
+
Override the `query_params_handler` method to handle query params
|
|
102
|
+
and return a filtered queryset.
|
|
103
|
+
|
|
104
|
+
## Methods:
|
|
105
|
+
- **create_view**: Creates a new object.
|
|
106
|
+
- **list_view**: Lists all objects.
|
|
107
|
+
- **retrieve_view**: Retrieves an object by its primary key.
|
|
108
|
+
- **update_view**: Updates an object by its primary key.
|
|
109
|
+
- **delete_view**: Deletes an object by its primary key.
|
|
110
|
+
- **views**: Override to add custom views.
|
|
111
|
+
- **add_views_to_route**: Adds the views to the API route.
|
|
112
|
+
|
|
113
|
+
## Example:
|
|
114
|
+
class MyModelViewSet(APIViewSet):
|
|
115
|
+
model = MyModel # Your Django model
|
|
116
|
+
api = my_api_instance # Your NinjaAPI instance
|
|
117
|
+
|
|
118
|
+
MyModelViewSet().add_views_to_route()
|
|
119
|
+
"""
|
|
120
|
+
|
|
69
121
|
model: ModelSerializer | Model
|
|
70
122
|
api: NinjaAPI
|
|
71
123
|
schema_in: Schema | None = None
|
|
@@ -80,6 +132,11 @@ class APIViewSet:
|
|
|
80
132
|
query_params: dict[str, tuple[type, ...]] = {}
|
|
81
133
|
disable: list[type[VIEW_TYPES]] = []
|
|
82
134
|
api_route_path: str = ""
|
|
135
|
+
list_docs = "List all objects."
|
|
136
|
+
create_docs = "Create a new object."
|
|
137
|
+
retrieve_docs = "Retrieve a specific object by its primary key."
|
|
138
|
+
update_docs = "Update an object by its primary key."
|
|
139
|
+
delete_docs = "Delete an object by its primary key."
|
|
83
140
|
|
|
84
141
|
def __init__(self) -> None:
|
|
85
142
|
self.error_codes = ERROR_CODES
|
|
@@ -87,10 +144,13 @@ class APIViewSet:
|
|
|
87
144
|
self.schema_out, self.schema_in, self.schema_update = self.get_schemas()
|
|
88
145
|
self.path_schema = self._generate_path_schema()
|
|
89
146
|
self.filters_schema = self._generate_filters_schema()
|
|
90
|
-
self.
|
|
147
|
+
self.model_verbose_name = self.model._meta.verbose_name.capitalize()
|
|
148
|
+
self.router_tag = self.model_verbose_name
|
|
91
149
|
self.router = Router(tags=[self.router_tag])
|
|
92
150
|
self.path = "/"
|
|
151
|
+
self.get_path = ""
|
|
93
152
|
self.path_retrieve = f"{{{self.model_util.model_pk_name}}}/"
|
|
153
|
+
self.get_path_retrieve = f"/{{{self.model_util.model_pk_name}}}"
|
|
94
154
|
self.api_route_path = (
|
|
95
155
|
self.api_route_path or self.model_util.verbose_name_path_resolver()
|
|
96
156
|
)
|
|
@@ -115,13 +175,13 @@ class APIViewSet:
|
|
|
115
175
|
|
|
116
176
|
def get_view_auth(self):
|
|
117
177
|
return self._auth_view("get")
|
|
118
|
-
|
|
178
|
+
|
|
119
179
|
def post_view_auth(self):
|
|
120
180
|
return self._auth_view("post")
|
|
121
|
-
|
|
181
|
+
|
|
122
182
|
def patch_view_auth(self):
|
|
123
183
|
return self._auth_view("patch")
|
|
124
|
-
|
|
184
|
+
|
|
125
185
|
def delete_view_auth(self):
|
|
126
186
|
return self._auth_view("delete")
|
|
127
187
|
|
|
@@ -162,9 +222,11 @@ class APIViewSet:
|
|
|
162
222
|
@self.router.post(
|
|
163
223
|
self.path,
|
|
164
224
|
auth=self.post_view_auth(),
|
|
225
|
+
summary=f"Create {self.model._meta.verbose_name.capitalize()}",
|
|
226
|
+
description=self.create_docs,
|
|
165
227
|
response={201: self.schema_out, self.error_codes: GenericMessageSchema},
|
|
166
228
|
)
|
|
167
|
-
async def create(request: HttpRequest, data: self.schema_in):
|
|
229
|
+
async def create(request: HttpRequest, data: self.schema_in): # type: ignore
|
|
168
230
|
return 201, await self.model_util.create_s(request, data, self.schema_out)
|
|
169
231
|
|
|
170
232
|
create.__name__ = f"create_{self.model_util.model_name}"
|
|
@@ -172,8 +234,10 @@ class APIViewSet:
|
|
|
172
234
|
|
|
173
235
|
def list_view(self):
|
|
174
236
|
@self.router.get(
|
|
175
|
-
self.
|
|
237
|
+
self.get_path,
|
|
176
238
|
auth=self.get_view_auth(),
|
|
239
|
+
summary=f"List {self.model._meta.verbose_name_plural.capitalize()}",
|
|
240
|
+
description=self.list_docs,
|
|
177
241
|
response={
|
|
178
242
|
200: List[self.schema_out],
|
|
179
243
|
self.error_codes: GenericMessageSchema,
|
|
@@ -181,7 +245,8 @@ class APIViewSet:
|
|
|
181
245
|
)
|
|
182
246
|
@paginate(self.pagination_class)
|
|
183
247
|
async def list(
|
|
184
|
-
request: HttpRequest,
|
|
248
|
+
request: HttpRequest,
|
|
249
|
+
filters: Query[self.filters_schema] = None, # type: ignore
|
|
185
250
|
):
|
|
186
251
|
qs = self.model.objects.select_related()
|
|
187
252
|
if isinstance(self.model, ModelSerializerMeta):
|
|
@@ -202,11 +267,13 @@ class APIViewSet:
|
|
|
202
267
|
|
|
203
268
|
def retrieve_view(self):
|
|
204
269
|
@self.router.get(
|
|
205
|
-
self.
|
|
270
|
+
self.get_path_retrieve,
|
|
206
271
|
auth=self.get_view_auth(),
|
|
272
|
+
summary=f"Retrieve {self.model._meta.verbose_name.capitalize()}",
|
|
273
|
+
description=self.retrieve_docs,
|
|
207
274
|
response={200: self.schema_out, self.error_codes: GenericMessageSchema},
|
|
208
275
|
)
|
|
209
|
-
async def retrieve(request: HttpRequest, pk: Path[self.path_schema]):
|
|
276
|
+
async def retrieve(request: HttpRequest, pk: Path[self.path_schema]): # type: ignore
|
|
210
277
|
obj = await self.model_util.get_object(request, self._get_pk(pk))
|
|
211
278
|
return await self.model_util.read_s(request, obj, self.schema_out)
|
|
212
279
|
|
|
@@ -217,10 +284,14 @@ class APIViewSet:
|
|
|
217
284
|
@self.router.patch(
|
|
218
285
|
self.path_retrieve,
|
|
219
286
|
auth=self.patch_view_auth(),
|
|
287
|
+
summary=f"Update {self.model._meta.verbose_name.capitalize()}",
|
|
288
|
+
description=self.update_docs,
|
|
220
289
|
response={200: self.schema_out, self.error_codes: GenericMessageSchema},
|
|
221
290
|
)
|
|
222
291
|
async def update(
|
|
223
|
-
request: HttpRequest,
|
|
292
|
+
request: HttpRequest,
|
|
293
|
+
data: self.schema_update, # type: ignore
|
|
294
|
+
pk: Path[self.path_schema], # type: ignore
|
|
224
295
|
):
|
|
225
296
|
return await self.model_util.update_s(
|
|
226
297
|
request, data, self._get_pk(pk), self.schema_out
|
|
@@ -233,9 +304,11 @@ class APIViewSet:
|
|
|
233
304
|
@self.router.delete(
|
|
234
305
|
self.path_retrieve,
|
|
235
306
|
auth=self.delete_view_auth(),
|
|
307
|
+
summary=f"Delete {self.model._meta.verbose_name.capitalize()}",
|
|
308
|
+
description=self.delete_docs,
|
|
236
309
|
response={204: None, self.error_codes: GenericMessageSchema},
|
|
237
310
|
)
|
|
238
|
-
async def delete(request: HttpRequest, pk: Path[self.path_schema]):
|
|
311
|
+
async def delete(request: HttpRequest, pk: Path[self.path_schema]): # type: ignore
|
|
239
312
|
return 204, await self.model_util.delete_s(request, self._get_pk(pk))
|
|
240
313
|
|
|
241
314
|
delete.__name__ = f"delete_{self.model_util.model_name}"
|
|
@@ -274,7 +347,7 @@ class APIViewSet:
|
|
|
274
347
|
pass
|
|
275
348
|
"""
|
|
276
349
|
|
|
277
|
-
def
|
|
350
|
+
def _add_views(self):
|
|
278
351
|
if "all" in self.disable:
|
|
279
352
|
self.views()
|
|
280
353
|
return self.router
|
|
@@ -290,6 +363,6 @@ class APIViewSet:
|
|
|
290
363
|
|
|
291
364
|
def add_views_to_route(self):
|
|
292
365
|
return self.api.add_router(
|
|
293
|
-
f"{self.api_route_path}
|
|
294
|
-
self.
|
|
366
|
+
f"{self.api_route_path}",
|
|
367
|
+
self._add_views(),
|
|
295
368
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|