|
1 | 1 | import typing as t |
2 | 2 |
|
3 | 3 | from ninja.orm.fields import TYPES |
4 | | -from ninja.params import Body, Path |
5 | 4 |
|
6 | 5 | from ninja_extra.constants import ROUTE_FUNCTION |
7 | 6 |
|
8 | | -from ... import status |
9 | | -from ...exceptions import NotFound |
10 | | -from ...pagination import paginate |
11 | | -from ..route import route |
| 7 | +from .endpoints import ModelEndpointFactory |
12 | 8 | from .schemas import ModelConfig |
13 | 9 |
|
14 | 10 | try: |
@@ -155,178 +151,102 @@ def _add_to_controller(self, func: t.Callable) -> None: |
155 | 151 | self._api_controller_instance.add_controller_route_function(route_function) |
156 | 152 |
|
157 | 153 | def _register_create_endpoint(self) -> None: |
158 | | - create_schema_in = self._config.create_schema |
159 | | - create_schema_out = self._retrieve_schema |
160 | | - model_name = self._model_name |
161 | | - |
162 | | - @route.post( |
163 | | - "/", |
164 | | - response={201: create_schema_out}, |
| 154 | + create_item = ModelEndpointFactory.create( |
| 155 | + schema_in=self._create_schema, # type: ignore[arg-type] |
| 156 | + schema_out=self._retrieve_schema, # type: ignore[arg-type] |
165 | 157 | url_name=f"{self._model_name}-create", |
166 | | - description=f"Create {model_name} item", |
| 158 | + description=f"Create {self._model_name} item", |
| 159 | + summary="Create an item", |
167 | 160 | ) |
168 | | - def create_item( |
169 | | - self: "ModelControllerBase", |
170 | | - data: create_schema_in = Body(default=...), # type:ignore[valid-type] |
171 | | - ) -> t.Any: |
172 | | - instance = self.service.create(data) |
173 | | - assert instance, "`service.create` must return a value" |
174 | | - return instance |
175 | 161 |
|
176 | 162 | self._add_to_controller(create_item) |
177 | 163 |
|
178 | 164 | def _register_update_endpoint(self) -> None: |
179 | | - update_schema_in = self._update_schema |
180 | | - update_schema_out = self._retrieve_schema |
181 | | - |
182 | | - _pk_type = self._pk_type |
183 | 165 | _path = "/{%s:%s}" % ( |
184 | | - _pk_type.__name__, |
| 166 | + self._pk_type.__name__, |
185 | 167 | self._model_pk_name, |
186 | 168 | ) |
187 | | - model_name = self._model_name |
188 | | - model_pk_name = self._model_pk_name |
189 | | - |
190 | | - @route.put( |
191 | | - _path, |
192 | | - response={200: update_schema_out}, |
193 | | - url_name=f"{model_pk_name}-put", |
194 | | - description=f"""Update {model_name} item by {model_pk_name}""", |
| 169 | + |
| 170 | + update_item = ModelEndpointFactory.update( |
| 171 | + path=_path, |
| 172 | + lookup_field=self._model_pk_name, |
| 173 | + schema_in=self._update_schema, # type: ignore[arg-type] |
| 174 | + schema_out=self._retrieve_schema, # type: ignore[arg-type] |
| 175 | + url_name=f"{self._model_pk_name}-put", |
| 176 | + description=f"""Update {self._model_name} item by {self._model_pk_name}""", |
| 177 | + summary="Update an item", |
195 | 178 | ) |
196 | | - def update_item( |
197 | | - self: "ModelControllerBase", |
198 | | - pk: _pk_type = Path( # type:ignore[valid-type] |
199 | | - default=..., alias=model_pk_name |
200 | | - ), |
201 | | - data: update_schema_in = Body(default=...), # type:ignore[valid-type] |
202 | | - ) -> t.Any: |
203 | | - obj = self.service.get_one(pk=pk) |
204 | | - if not obj: |
205 | | - raise NotFound() |
206 | | - self.check_object_permissions(obj) |
207 | | - instance = self.service.update(instance=obj, schema=data) |
208 | | - assert instance, "`service.update` must return a value" |
209 | | - return instance |
210 | 179 |
|
211 | 180 | self._add_to_controller(update_item) |
212 | 181 |
|
213 | 182 | def _register_patch_endpoint(self) -> None: |
214 | | - update_schema_in = self._patch_schema |
215 | | - update_schema_out = self._retrieve_schema |
216 | | - |
217 | 183 | _pk_type = self._pk_type |
218 | 184 | _path = "/{%s:%s}" % ( |
219 | 185 | _pk_type.__name__, |
220 | 186 | self._model_pk_name, |
221 | 187 | ) |
222 | | - model_name = self._model_name |
223 | | - model_pk_name = self._model_pk_name |
224 | 188 |
|
225 | | - @route.patch( |
226 | | - _path, |
227 | | - response={200: update_schema_out}, |
| 189 | + patch_item = ModelEndpointFactory.patch( |
| 190 | + path=_path, |
| 191 | + lookup_field=self._model_pk_name, |
| 192 | + schema_out=self._retrieve_schema, # type: ignore[arg-type] |
| 193 | + schema_in=self._patch_schema, # type: ignore[arg-type] |
228 | 194 | url_name=f"{self._model_pk_name}-patch", |
229 | | - description=f"""Patch {model_name} item by {model_pk_name}""", |
| 195 | + description=f"""Patch {self._model_name} item by {self._model_pk_name}""", |
| 196 | + summary="Patch an item", |
230 | 197 | ) |
231 | | - def patch_item( |
232 | | - self: "ModelControllerBase", |
233 | | - pk: _pk_type = Path( # type:ignore[valid-type] |
234 | | - default=..., alias=self._model_pk_name |
235 | | - ), |
236 | | - data: update_schema_in = Body(default=...), # type:ignore[valid-type] |
237 | | - ) -> t.Any: |
238 | | - obj = self.service.get_one(pk=pk) |
239 | | - if not obj: |
240 | | - raise NotFound() |
241 | | - self.check_object_permissions(obj) |
242 | | - instance = self.service.patch(instance=obj, schema=data) |
243 | | - assert instance, "`perform_patch()` must return a value" |
244 | | - return instance |
245 | 198 |
|
246 | 199 | self._add_to_controller(patch_item) |
247 | 200 |
|
248 | 201 | def _register_find_one_endpoint(self) -> None: |
249 | | - retrieve_schema = self._config.retrieve_schema |
250 | | - _pk_type = self._pk_type |
251 | 202 | _path = "/{%s:%s}" % ( |
252 | | - _pk_type.__name__, |
| 203 | + self._pk_type.__name__, |
253 | 204 | self._model_pk_name, |
254 | 205 | ) |
255 | | - model_name = self._model_name |
256 | | - model_pk_name = self._model_pk_name |
257 | 206 |
|
258 | | - @route.get( |
259 | | - _path, |
260 | | - response={200: retrieve_schema}, |
| 207 | + get_item = ModelEndpointFactory.retrieve( |
| 208 | + path=_path, |
| 209 | + lookup_field=self._model_pk_name, |
| 210 | + schema_out=self._retrieve_schema, # type: ignore[arg-type] |
261 | 211 | url_name=f"{self._model_pk_name}-get-item", |
262 | | - description=f"""Get {model_name} item by {model_pk_name}""", |
| 212 | + description=f"""Get {self._model_name} item by {self._model_pk_name}""", |
| 213 | + summary="Get a specific item", |
263 | 214 | ) |
264 | | - def get_item( |
265 | | - self: "ModelControllerBase", |
266 | | - pk: _pk_type = Path( # type:ignore[valid-type] |
267 | | - default=..., alias=self._model_pk_name |
268 | | - ), |
269 | | - ) -> t.Any: |
270 | | - obj = self.service.get_one(pk=pk) |
271 | | - if not obj: |
272 | | - raise NotFound() |
273 | | - self.check_object_permissions(obj) |
274 | | - return obj |
275 | 215 |
|
276 | 216 | self._add_to_controller(get_item) |
277 | 217 |
|
278 | 218 | def _register_list_endpoint(self) -> None: |
279 | 219 | paginate_kwargs: t.Dict[str, t.Any] = {} |
280 | | - pagination_response_schema = self._config.pagination.pagination_schema |
281 | | - pagination_class = self._config.pagination.klass |
282 | | - retrieve_schema = self._retrieve_schema |
283 | | - model_name = self._model_name |
284 | 220 |
|
285 | 221 | if self._config.pagination.paginate_by: |
286 | 222 | paginate_kwargs.update(page_size=self._config.pagination.paginate_by) |
287 | 223 |
|
288 | | - @route.get( |
289 | | - "/", |
290 | | - response={ |
291 | | - 200: pagination_response_schema[retrieve_schema] # type:ignore[index] |
292 | | - }, |
| 224 | + list_items = ModelEndpointFactory.list( |
| 225 | + path="/", |
| 226 | + schema_out=self._retrieve_schema, # type: ignore[arg-type] |
| 227 | + pagination_class=self._config.pagination.klass, |
| 228 | + pagination_response_schema=self._config.pagination.pagination_schema, |
| 229 | + description=f"List {self._model_name} model items", |
293 | 230 | url_name=f"{self._model_pk_name}-list", |
294 | | - description=f"List {model_name} model items", |
| 231 | + summary="List Items", |
| 232 | + **paginate_kwargs, |
295 | 233 | ) |
296 | | - @paginate(pagination_class, **paginate_kwargs) |
297 | | - def list_items(self: "ModelControllerBase") -> t.Any: |
298 | | - return self.service.get_all() |
299 | 234 |
|
300 | 235 | self._add_to_controller(list_items) |
301 | 236 |
|
302 | 237 | def _register_delete_endpoint(self) -> None: |
303 | | - _pk_type = self._pk_type |
304 | 238 | _path = "/{%s:%s}" % ( |
305 | | - _pk_type.__name__, |
| 239 | + self._pk_type.__name__, |
306 | 240 | self._model_pk_name, |
307 | 241 | ) |
308 | | - model_name = self._model_name |
309 | 242 |
|
310 | | - @route.delete( |
311 | | - _path, |
| 243 | + delete_item = ModelEndpointFactory.delete( |
| 244 | + path=_path, |
| 245 | + lookup_field=self._model_pk_name, |
312 | 246 | url_name=f"{self._model_pk_name}-delete", |
313 | | - response={204: str}, |
314 | | - description=f"""Delete {model_name} item""", |
| 247 | + description=f"""Delete {self._model_name} item""", |
| 248 | + summary="Delete an item", |
315 | 249 | ) |
316 | | - def delete_item( |
317 | | - self: "ModelControllerBase", |
318 | | - pk: _pk_type = Path( # type:ignore[valid-type] |
319 | | - default=..., alias=self._model_pk_name |
320 | | - ), |
321 | | - ) -> t.Any: |
322 | | - obj = self.service.get_one(pk=pk) |
323 | | - if not obj: |
324 | | - raise NotFound() |
325 | | - self.check_object_permissions(obj) |
326 | | - self.service.delete(instance=obj) |
327 | | - return self.create_response( |
328 | | - message="", status_code=status.HTTP_204_NO_CONTENT |
329 | | - ) |
330 | 250 |
|
331 | 251 | self._add_to_controller(delete_item) |
332 | 252 |
|
|
0 commit comments