Coverage for extras/api/routers.py: 100%
13 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
1from rest_framework.routers import Route
3from netbox.api.routers import NetBoxRouter
5from .views import ScriptViewSet
7__all__ = (
8 'ScriptRouter',
9)
12class ScriptRouter(NetBoxRouter):
13 """
14 Extend NetBoxRouter to map POST on the script detail route to ScriptViewSet.run(). DRF's detail route
15 maps only the standard CRUD methods; absent this, run() must be declared as a raw post() method, which
16 binds to every route of the ViewSet and is invisible to per-action permissions & schema generation.
17 """
18 def get_routes(self, viewset):
19 if not issubclass(viewset, ScriptViewSet):
20 return super().get_routes(viewset)
22 # Extend the detail route template. Applied before super() expands the templates so that any
23 # @action routes are untouched; _replace() avoids mutating the templates shared by all routers.
24 routes = self.routes
25 self.routes = [
26 route._replace(mapping={**route.mapping, 'post': 'run'})
27 if isinstance(route, Route) and route.detail else route
28 for route in routes
29 ]
31 try:
32 return super().get_routes(viewset)
33 finally:
34 self.routes = routes