Skip to content

Commit 4f26d14

Browse files
committed
Refactoring
1 parent e86725e commit 4f26d14

File tree

1 file changed

+139
-139
lines changed

1 file changed

+139
-139
lines changed

ninja_extra/controllers/base.py

Lines changed: 139 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,139 @@ def compute_api_route_function(
6565
api_controller_instance.add_operation_from_route_function(cls_route_function)
6666

6767

68+
class ControllerBase(ABC):
69+
"""
70+
Abstract Controller Base implementation all Controller class should implement
71+
72+
Example:
73+
---------
74+
```python
75+
from ninja_extra import api_controller, ControllerBase, http_get
76+
77+
@api_controller
78+
class SomeController(ControllerBase):
79+
@http_get()
80+
def some_method_name(self):
81+
...
82+
```
83+
Inheritance Example
84+
-------------------
85+
```python
86+
87+
@api_controller
88+
class AnotherController(SomeController):
89+
@http_get()
90+
def some_method_name(self):
91+
...
92+
```
93+
"""
94+
95+
# `_api_controller` a reference to APIController instance
96+
_api_controller: Optional["APIController"] = None
97+
98+
# `api` a reference to NinjaExtraAPI on APIController registration
99+
api: Optional[NinjaAPI] = None
100+
101+
# `context` variable will change based on the route function called on the APIController
102+
# that way we can get some specific items things that belong the route function during execution
103+
context: Optional["RouteContext"] = None
104+
105+
Ok = Ok
106+
Id = Id
107+
Detail = Detail
108+
bad_request = bad_request
109+
110+
@classmethod
111+
def get_api_controller(cls) -> "APIController":
112+
if not cls._api_controller:
113+
raise MissingAPIControllerDecoratorException(
114+
"api_controller not found. "
115+
"Did you forget to use the `api_controller` decorator"
116+
)
117+
return cls._api_controller
118+
119+
@classmethod
120+
def permission_denied(cls, permission: BasePermission) -> None:
121+
message = getattr(permission, "message", None)
122+
raise PermissionDenied(message)
123+
124+
def get_object_or_exception(
125+
self,
126+
klass: Union[Type[Model], QuerySet],
127+
error_message: str = None,
128+
exception: Type[APIException] = NotFound,
129+
**kwargs: Any,
130+
) -> Any:
131+
obj = get_object_or_exception(
132+
klass=klass, error_message=error_message, exception=exception, **kwargs
133+
)
134+
self.check_object_permissions(obj)
135+
return obj
136+
137+
def get_object_or_none(
138+
self, klass: Union[Type[Model], QuerySet], **kwargs: Any
139+
) -> Optional[Any]:
140+
obj = get_object_or_none(klass=klass, **kwargs)
141+
if obj:
142+
self.check_object_permissions(obj)
143+
return obj
144+
145+
def _get_permissions(self) -> Iterable[BasePermission]:
146+
"""
147+
Instantiates and returns the list of permissions that this view requires.
148+
"""
149+
if not self.context:
150+
return
151+
152+
for permission_class in self.context.permission_classes:
153+
permission_instance = permission_class()
154+
yield permission_instance
155+
156+
def check_permissions(self) -> None:
157+
"""
158+
Check if the request should be permitted.
159+
Raises an appropriate exception if the request is not permitted.
160+
"""
161+
for permission in self._get_permissions():
162+
if (
163+
self.context
164+
and self.context.request
165+
and not permission.has_permission(
166+
request=self.context.request, controller=self
167+
)
168+
):
169+
self.permission_denied(permission)
170+
171+
def check_object_permissions(self, obj: Union[Any, Model]) -> None:
172+
"""
173+
Check if the request should be permitted for a given object.
174+
Raises an appropriate exception if the request is not permitted.
175+
"""
176+
for permission in self._get_permissions():
177+
if (
178+
self.context
179+
and self.context.request
180+
and not permission.has_object_permission(
181+
request=self.context.request, controller=self, obj=obj
182+
)
183+
):
184+
self.permission_denied(permission)
185+
186+
def create_response(
187+
self, message: Any, status_code: int = 200, **kwargs: Any
188+
) -> HttpResponse:
189+
assert self.api and self.context and self.context.request
190+
content = self.api.renderer.render(
191+
self.context.request, message, response_status=status_code
192+
)
193+
content_type = "{}; charset={}".format(
194+
self.api.renderer.media_type, self.api.renderer.charset
195+
)
196+
return HttpResponse(
197+
content, status=status_code, content_type=content_type, **kwargs
198+
)
199+
200+
68201
class APIController:
69202
_PATH_PARAMETER_COMPONENT_RE = r"{(?:(?P<converter>[^>:]+):)?(?P<parameter>[^>]+)}"
70203

@@ -267,147 +400,14 @@ def add_api_operation(
267400
return operation
268401

269402

270-
class ControllerBase(ABC):
271-
"""
272-
Abstract Controller Base implementation all Controller class should implement
273-
274-
Example:
275-
---------
276-
```python
277-
from ninja_extra import api_controller, ControllerBase, http_get
278-
279-
@api_controller
280-
class SomeController(ControllerBase):
281-
@http_get()
282-
def some_method_name(self):
283-
...
284-
```
285-
Inheritance Example
286-
-------------------
287-
```python
288-
289-
@api_controller
290-
class AnotherController(SomeController):
291-
@http_get()
292-
def some_method_name(self):
293-
...
294-
```
295-
"""
296-
297-
# `_api_controller` a reference to APIController instance
298-
_api_controller: Optional[APIController] = None
299-
300-
# `api` a reference to NinjaExtraAPI on APIController registration
301-
api: Optional[NinjaAPI] = None
302-
303-
# `context` variable will change based on the route function called on the APIController
304-
# that way we can get some specific items things that belong the route function during execution
305-
context: Optional["RouteContext"] = None
306-
307-
Ok = Ok
308-
Id = Id
309-
Detail = Detail
310-
bad_request = bad_request
311-
312-
@classmethod
313-
def get_api_controller(cls) -> APIController:
314-
if not cls._api_controller:
315-
raise MissingAPIControllerDecoratorException(
316-
"api_controller not found. "
317-
"Did you forget to use the `api_controller` decorator"
318-
)
319-
return cls._api_controller
320-
321-
@classmethod
322-
def permission_denied(cls, permission: BasePermission) -> None:
323-
message = getattr(permission, "message", None)
324-
raise PermissionDenied(message)
325-
326-
def get_object_or_exception(
327-
self,
328-
klass: Union[Type[Model], QuerySet],
329-
error_message: str = None,
330-
exception: Type[APIException] = NotFound,
331-
**kwargs: Any,
332-
) -> Any:
333-
obj = get_object_or_exception(
334-
klass=klass, error_message=error_message, exception=exception, **kwargs
335-
)
336-
self.check_object_permissions(obj)
337-
return obj
338-
339-
def get_object_or_none(
340-
self, klass: Union[Type[Model], QuerySet], **kwargs: Any
341-
) -> Optional[Any]:
342-
obj = get_object_or_none(klass=klass, **kwargs)
343-
if obj:
344-
self.check_object_permissions(obj)
345-
return obj
346-
347-
def _get_permissions(self) -> Iterable[BasePermission]:
348-
"""
349-
Instantiates and returns the list of permissions that this view requires.
350-
"""
351-
if not self.context:
352-
return
353-
354-
for permission_class in self.context.permission_classes:
355-
permission_instance = permission_class()
356-
yield permission_instance
357-
358-
def check_permissions(self) -> None:
359-
"""
360-
Check if the request should be permitted.
361-
Raises an appropriate exception if the request is not permitted.
362-
"""
363-
for permission in self._get_permissions():
364-
if (
365-
self.context
366-
and self.context.request
367-
and not permission.has_permission(
368-
request=self.context.request, controller=self
369-
)
370-
):
371-
self.permission_denied(permission)
372-
373-
def check_object_permissions(self, obj: Union[Any, Model]) -> None:
374-
"""
375-
Check if the request should be permitted for a given object.
376-
Raises an appropriate exception if the request is not permitted.
377-
"""
378-
for permission in self._get_permissions():
379-
if (
380-
self.context
381-
and self.context.request
382-
and not permission.has_object_permission(
383-
request=self.context.request, controller=self, obj=obj
384-
)
385-
):
386-
self.permission_denied(permission)
387-
388-
def create_response(
389-
self, message: Any, status_code: int = 200, **kwargs: Any
390-
) -> HttpResponse:
391-
assert self.api and self.context and self.context.request
392-
content = self.api.renderer.render(
393-
self.context.request, message, response_status=status_code
394-
)
395-
content_type = "{}; charset={}".format(
396-
self.api.renderer.media_type, self.api.renderer.charset
397-
)
398-
return HttpResponse(
399-
content, status=status_code, content_type=content_type, **kwargs
400-
)
401-
402-
403403
@overload
404-
def api_controller() -> Type[ControllerBase]: # type: ignore # pragma: no cover
404+
def api_controller(prefix_or_class: Type) -> Type[ControllerBase]: # pragma: no cover
405405
...
406406

407407

408408
@overload
409409
def api_controller(
410-
prefix: str = "",
410+
prefix_or_class: str = "",
411411
auth: Any = NOT_SET,
412412
tags: Union[Optional[List[str]], str] = None,
413413
permissions: Optional["PermissionType"] = None,
@@ -417,24 +417,24 @@ def api_controller(
417417

418418

419419
def api_controller(
420-
prefix: Union[str, Type] = "",
420+
prefix_or_class: Union[str, Type] = "",
421421
auth: Any = NOT_SET,
422422
tags: Union[Optional[List[str]], str] = None,
423423
permissions: Optional["PermissionType"] = None,
424424
auto_import: bool = True,
425425
) -> Union[Type[ControllerBase], APIController]:
426-
if isinstance(prefix, type):
426+
if isinstance(prefix_or_class, type):
427427
_api_controller = APIController(
428428
prefix="",
429429
auth=auth,
430430
tags=tags,
431431
permissions=permissions,
432432
auto_import=auto_import,
433433
)
434-
return _api_controller(prefix)
434+
return _api_controller(prefix_or_class)
435435

436436
return APIController(
437-
prefix=prefix,
437+
prefix=prefix_or_class,
438438
auth=auth,
439439
tags=tags,
440440
permissions=permissions,

0 commit comments

Comments
 (0)