django-ninja-aio-crud 0.8.3__py3-none-any.whl → 0.9.0__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-ninja-aio-crud
3
- Version: 0.8.3
3
+ Version: 0.9.0
4
4
  Summary: Django Ninja AIO CRUD - Rest Framework
5
5
  Author: Giuseppe Casillo
6
6
  Requires-Python: >=3.10
@@ -1,4 +1,4 @@
1
- ninja_aio/__init__.py,sha256=Lu3EjRydPdUhQRi4sXWJ4ZPvHj3YIz5xkrGx5YaqW3s,119
1
+ ninja_aio/__init__.py,sha256=9ggtH4eyizZZc5TL9LqAobQd3fZltmcY6C_aEpvOiKc,119
2
2
  ninja_aio/api.py,sha256=Fe6l3YCy7MW5TY4-Lbl80CFuK2NT2Y7tHfmqPk6Mqak,1735
3
3
  ninja_aio/auth.py,sha256=fKboioU4sezPukKJukIwiboxml_KV7irhCH3vGYt5pU,1008
4
4
  ninja_aio/exceptions.py,sha256=gPnZX1Do2GXudbU8wDYkwhO70Qj0ZNrIJJ2UXRs9vYk,2241
@@ -7,8 +7,8 @@ ninja_aio/parsers.py,sha256=e_4lGCPV7zs-HTqtdJTc8yQD2KPAn9njbL8nF_Mmgkc,153
7
7
  ninja_aio/renders.py,sha256=0eYklRKd59aV4cZDom5vLZyA99Ob17OwkpMybsRXvyg,1970
8
8
  ninja_aio/schemas.py,sha256=EgRkfhnzZqwGvdBmqlZixMtMcoD1ZxV_qzJ3fmaAy20,113
9
9
  ninja_aio/types.py,sha256=TJSGlA7bt4g9fvPhJ7gzH5tKbLagPmZUzfgttEOp4xs,468
10
- ninja_aio/views.py,sha256=O08HWNN8OZo1fYiuL4VFdpi4H-YvRKWSXD4ECavoXEQ,10127
11
- django_ninja_aio_crud-0.8.3.dist-info/licenses/LICENSE,sha256=yrDAYcm0gRp_Qyzo3GQa4BjYjWRkAhGC8QRva__RYq0,1073
12
- django_ninja_aio_crud-0.8.3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
13
- django_ninja_aio_crud-0.8.3.dist-info/METADATA,sha256=XfhUYJk4MDGYbE6SbMd8bhc27rmEOw6SQr1mwZnzCAs,14138
14
- django_ninja_aio_crud-0.8.3.dist-info/RECORD,,
10
+ ninja_aio/views.py,sha256=VQEtnVF4pPqA1RVk_3ocDCa0IOnF7SAAhz612K9pjkU,13950
11
+ django_ninja_aio_crud-0.9.0.dist-info/licenses/LICENSE,sha256=yrDAYcm0gRp_Qyzo3GQa4BjYjWRkAhGC8QRva__RYq0,1073
12
+ django_ninja_aio_crud-0.9.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
13
+ django_ninja_aio_crud-0.9.0.dist-info/METADATA,sha256=qaJdDyHP6xQm6oTFqsiv2j7rsfCsv0sU5fJ21WOGvm4,14138
14
+ django_ninja_aio_crud-0.9.0.dist-info/RECORD,,
ninja_aio/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Django Ninja AIO CRUD - Rest Framework"""
2
2
 
3
- __version__ = "0.8.3"
3
+ __version__ = "0.9.0"
4
4
 
5
5
  from .api import NinjaAIO
6
6
 
ninja_aio/views.py CHANGED
@@ -57,15 +57,67 @@ class APIView:
57
57
  pass
58
58
  """
59
59
 
60
- def add_views(self):
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}/", self.add_views())
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.router_tag = self.model_util.model_name.capitalize()
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): # type: ignore
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.path,
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, filters: Query[self.filters_schema] = None # type: ignore
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.path_retrieve,
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]): # type: ignore
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, data: self.schema_update, pk: Path[self.path_schema] # type: ignore
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]): # type: ignore
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 add_views(self):
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.add_views(),
366
+ f"{self.api_route_path}",
367
+ self._add_views(),
295
368
  )