Skip to content

Commit 37536c8

Browse files
authored
Merge pull request #315 from eadwinCode/chores_22_nove
chores: Refactored Url Namespace and Unique Route Operation Id
2 parents 2ba70ad + ff6e682 commit 37536c8

File tree

4 files changed

+29
-22
lines changed

4 files changed

+29
-22
lines changed

docs/api_controller/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ The fifth argument, `auto_import`, defaults to true, which automatically adds yo
4545

4646
The sixth argument, `urls_namespace`, defaults to `Controller Class Name`, or if set will nest the routes of this controller under their own namespace.
4747

48-
The seventh argument, `append_unique_op_id`, defaults to true, which appends a unique operation id suffix to the controller's routes to avoid conflicts.
48+
The seventh argument, `use_unique_op_id`, defaults to true, which appends a unique operation id suffix to the controller's routes to avoid conflicts.
4949

5050
for example:
5151

ninja_extra/controllers/base.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ def __init__(
404404
permissions: Optional[List[BasePermissionType]] = None,
405405
auto_import: bool = True,
406406
urls_namespace: Optional[str] = None,
407-
append_unique_op_id: bool = True
407+
use_unique_op_id: bool = True,
408408
) -> None:
409409
self.prefix = prefix
410410
# Optional controller-level URL namespace. Applied to all route paths.
@@ -414,7 +414,7 @@ def __init__(
414414

415415
self.tags = tags # type: ignore
416416
self.throttle = throttle
417-
self.append_unique_op_id = append_unique_op_id
417+
self.use_unique_op_id = use_unique_op_id
418418

419419
self.auto_import: bool = auto_import # set to false and it would be ignored when api.auto_discover is called
420420
# `controller_class` target class that the APIController wraps
@@ -496,11 +496,14 @@ def __call__(self, cls: ControllerClassType) -> ControllerClassType:
496496
item(**throttling_init_kwargs) for item in cls.throttling_classes
497497
]
498498

499+
class_name = str(cls.__name__).lower().replace("controller", "")
499500
if not self.tags:
500-
tag = str(cls.__name__).lower().replace("controller", "")
501-
self.tags = [tag]
501+
self.tags = [class_name]
502502

503503
self._controller_class = cls
504+
if not self.urls_namespace:
505+
# if urls_namespace is not provided, use the class name as the namespace
506+
self.urls_namespace = class_name
504507

505508
if issubclass(cls, ModelControllerBase):
506509
if cls.model_config:
@@ -560,6 +563,7 @@ def add_controller_route_function(self, route_function: RouteFunction) -> None:
560563

561564
def urls_paths(self, prefix: str) -> Iterator[Union[URLPattern, URLResolver]]:
562565
namespaced_patterns: List[URLPattern] = []
566+
assert self.urls_namespace, "urls_namespace is required"
563567

564568
for path, path_view in self.path_operations.items():
565569
path = path.replace("{", "<").replace("}", ">")
@@ -576,15 +580,15 @@ def urls_paths(self, prefix: str) -> Iterator[Union[URLPattern, URLResolver]]:
576580
else:
577581
pattern = django_path(route, view)
578582

579-
if self.urls_namespace:
580-
namespaced_patterns.append(pattern)
581-
else:
582-
yield pattern
583+
namespaced_patterns.append(pattern)
583584

584-
if self.urls_namespace and namespaced_patterns:
585+
if namespaced_patterns:
585586
yield django_path(
586587
"",
587-
include((namespaced_patterns, self.urls_namespace), namespace=self.urls_namespace),
588+
include(
589+
(namespaced_patterns, self.urls_namespace),
590+
namespace=self.urls_namespace,
591+
),
588592
)
589593

590594
def __repr__(self) -> str: # pragma: no cover
@@ -602,7 +606,7 @@ def _add_operation_from_route_function(self, route_function: RouteFunction) -> N
602606
route_function.route.route_params.operation_id = (
603607
f"{controller_name}_{route_function.route.view_func.__name__}"
604608
)
605-
if self.append_unique_op_id:
609+
if self.use_unique_op_id:
606610
route_function.route.route_params.operation_id += (
607611
f"_{uuid.uuid4().hex[:8]}"
608612
)
@@ -695,7 +699,7 @@ def api_controller(
695699
permissions: Optional[List[BasePermissionType]] = None,
696700
auto_import: bool = True,
697701
urls_namespace: Optional[str] = None,
698-
append_unique_op_id: bool = True,
702+
use_unique_op_id: bool = True,
699703
) -> Callable[
700704
[Union[Type, Type[T]]], Union[Type[ControllerBase], Type[T]]
701705
]: # pragma: no cover
@@ -710,7 +714,7 @@ def api_controller(
710714
permissions: Optional[List[BasePermissionType]] = None,
711715
auto_import: bool = True,
712716
urls_namespace: Optional[str] = None,
713-
append_unique_op_id: bool = True,
717+
use_unique_op_id: bool = True,
714718
) -> Union[ControllerClassType, Callable[[ControllerClassType], ControllerClassType]]:
715719
if isinstance(prefix_or_class, type):
716720
return APIController(
@@ -720,7 +724,7 @@ def api_controller(
720724
permissions=permissions,
721725
auto_import=auto_import,
722726
throttle=throttle,
723-
append_unique_op_id=append_unique_op_id,
727+
use_unique_op_id=use_unique_op_id,
724728
urls_namespace=urls_namespace,
725729
)(prefix_or_class)
726730

@@ -732,7 +736,7 @@ def _decorator(cls: ControllerClassType) -> ControllerClassType:
732736
permissions=permissions,
733737
auto_import=auto_import,
734738
throttle=throttle,
735-
append_unique_op_id=append_unique_op_id,
739+
use_unique_op_id=use_unique_op_id,
736740
urls_namespace=urls_namespace,
737741
)(cls)
738742

tests/test_controller.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def example(self):
7575
pass
7676

7777

78-
@api_controller(append_unique_op_id=False)
78+
@api_controller(use_unique_op_id=False)
7979
class SomeControllerWithoutUniqueSuffix:
8080
@http_get("/example")
8181
def example(self):
@@ -373,8 +373,11 @@ def test_namespaced_controller_detail(client):
373373
response = client.get("/api/inventory-items/5")
374374
assert response.status_code == 200
375375
assert response.json() == {"id": 5, "name": "sample-5"}
376-
assert reverse("api-1.0.0:inventory:inventory-item-detail", kwargs={"item_id": 5}) == "/api/inventory-items/5"
376+
assert (
377+
reverse("api-1.0.0:inventory:inventory-item-detail", kwargs={"item_id": 5})
378+
== "/api/inventory-items/5"
379+
)
377380

378381

379382
def test_default_url_name(client):
380-
assert reverse("api-1.0.0:get_event", kwargs={"id": 5}) == "/api/events/5"
383+
assert reverse("api-1.0.0:event:get_event", kwargs={"id": 5}) == "/api/events/5"

tests/test_django_model.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ def test_with_client(client: Client):
2626

2727
def test_reverse():
2828
# check that url reversing works
29-
assert reverse("api-1.0.0:event-create-url-name") == "/api/events"
30-
assert reverse("api-1.0.0:event-list") == "/api/events"
31-
assert reverse("api-1.0.0:event-list-2") == "/api/events/list"
29+
assert reverse("api-1.0.0:event:event-create-url-name") == "/api/events"
30+
assert reverse("api-1.0.0:event:event-list") == "/api/events"
31+
assert reverse("api-1.0.0:event:event-list-2") == "/api/events/list"
3232

3333

3434
def json_payload(data):

0 commit comments

Comments
 (0)