Skip to content

Commit bf48a4f

Browse files
committed
Added support to register controllers through string imports
1 parent 3f2483e commit bf48a4f

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

ninja_extra/main.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
from importlib import import_module
2-
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Type, Union
2+
from typing import (
3+
Any,
4+
Callable,
5+
Dict,
6+
List,
7+
Optional,
8+
Sequence,
9+
Tuple,
10+
Type,
11+
Union,
12+
cast,
13+
)
314

415
from django.core.exceptions import ImproperlyConfigured
516
from django.http import HttpRequest, HttpResponse
617
from django.urls import URLPattern, URLResolver
7-
from django.utils.module_loading import module_has_submodule
18+
from django.utils.module_loading import import_string, module_has_submodule
819
from ninja import NinjaAPI
920
from ninja.constants import NOT_SET
1021
from ninja.openapi.docs import DocsBase, Swagger
@@ -94,9 +105,14 @@ def urls(self) -> Tuple[List[Union[URLResolver, URLPattern]], str, str]:
94105
)
95106

96107
def register_controllers(
97-
self, *controllers: Union[Type[ControllerBase], Type]
108+
self, *controllers: Union[Type[ControllerBase], Type, str]
98109
) -> None:
99110
for controller in controllers:
111+
if isinstance(controller, str):
112+
controller = cast(
113+
Union[Type[ControllerBase], Type], import_string(controller)
114+
)
115+
100116
if not issubclass(controller, ControllerBase):
101117
raise ImproperlyConfigured(
102118
f"{controller.__class__.__name__} class is not a controller"

tests/test_controller.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,15 @@ def test_controller_base_get_object_or_none_works(self):
207207
assert isinstance(ex, exceptions.PermissionDenied)
208208

209209

210+
def test_controller_registration_through_string():
211+
assert DisableAutoImportController.get_api_controller().registered is False
212+
213+
api = NinjaExtraAPI()
214+
api.register_controllers("tests.test_controller.DisableAutoImportController")
215+
216+
assert DisableAutoImportController.get_api_controller().registered
217+
218+
210219
@pytest.mark.skipif(django.VERSION < (3, 1), reason="requires django 3.1 or higher")
211220
def test_async_controller():
212221
api_controller_decorator = api_controller(

0 commit comments

Comments
 (0)