mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #4997: Introduce OrderedDefaultRouter; move root API views to views.py
This commit is contained in:
@ -14,6 +14,7 @@
|
||||
* [#4982](https://github.com/netbox-community/netbox/issues/4982) - Extended ObjectVar to allow filtering API query
|
||||
* [#4994](https://github.com/netbox-community/netbox/issues/4994) - Add `cable` attribute to PowerFeed API serializer
|
||||
* [#4996](https://github.com/netbox-community/netbox/issues/4996) - Add "connect" buttons to individual device component views
|
||||
* [#4997](https://github.com/netbox-community/netbox/issues/4997) - The browsable API now lists available endpoints alphabetically
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
|
@ -1,18 +1,9 @@
|
||||
from rest_framework import routers
|
||||
|
||||
from utilities.api import OrderedDefaultRouter
|
||||
from . import views
|
||||
|
||||
|
||||
class CircuitsRootView(routers.APIRootView):
|
||||
"""
|
||||
Circuits API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Circuits'
|
||||
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.APIRootView = CircuitsRootView
|
||||
router = OrderedDefaultRouter()
|
||||
router.APIRootView = views.CircuitsRootView
|
||||
|
||||
# Providers
|
||||
router.register('providers', views.ProviderViewSet)
|
||||
|
@ -2,6 +2,7 @@ from django.db.models import Count, Prefetch
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.routers import APIRootView
|
||||
|
||||
from circuits import filters
|
||||
from circuits.models import Provider, CircuitTermination, CircuitType, Circuit
|
||||
@ -12,6 +13,14 @@ from utilities.api import ModelViewSet
|
||||
from . import serializers
|
||||
|
||||
|
||||
class CircuitsRootView(APIRootView):
|
||||
"""
|
||||
Circuits API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Circuits'
|
||||
|
||||
|
||||
#
|
||||
# Providers
|
||||
#
|
||||
|
@ -1,18 +1,9 @@
|
||||
from rest_framework import routers
|
||||
|
||||
from utilities.api import OrderedDefaultRouter
|
||||
from . import views
|
||||
|
||||
|
||||
class DCIMRootView(routers.APIRootView):
|
||||
"""
|
||||
DCIM API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'DCIM'
|
||||
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.APIRootView = DCIMRootView
|
||||
router = OrderedDefaultRouter()
|
||||
router.APIRootView = views.DCIMRootView
|
||||
|
||||
# Sites
|
||||
router.register('regions', views.RegionViewSet)
|
||||
|
@ -11,6 +11,7 @@ from drf_yasg.utils import swagger_auto_schema
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.mixins import ListModelMixin
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.routers import APIRootView
|
||||
from rest_framework.viewsets import GenericViewSet, ViewSet
|
||||
|
||||
from circuits.models import Circuit
|
||||
@ -36,6 +37,14 @@ from . import serializers
|
||||
from .exceptions import MissingFilterException
|
||||
|
||||
|
||||
class DCIMRootView(APIRootView):
|
||||
"""
|
||||
DCIM API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'DCIM'
|
||||
|
||||
|
||||
# Mixins
|
||||
|
||||
class CableTraceMixin(object):
|
||||
|
@ -1,18 +1,9 @@
|
||||
from rest_framework import routers
|
||||
|
||||
from utilities.api import OrderedDefaultRouter
|
||||
from . import views
|
||||
|
||||
|
||||
class ExtrasRootView(routers.APIRootView):
|
||||
"""
|
||||
Extras API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Extras'
|
||||
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.APIRootView = ExtrasRootView
|
||||
router = OrderedDefaultRouter()
|
||||
router.APIRootView = views.ExtrasRootView
|
||||
|
||||
# Custom field choices
|
||||
router.register('_custom_field_choices', views.CustomFieldChoicesViewSet, basename='custom-field-choice')
|
||||
|
@ -8,6 +8,7 @@ from rest_framework import status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.routers import APIRootView
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
|
||||
from rq import Worker
|
||||
|
||||
@ -25,6 +26,14 @@ from utilities.utils import copy_safe_request
|
||||
from . import serializers
|
||||
|
||||
|
||||
class ExtrasRootView(APIRootView):
|
||||
"""
|
||||
Extras API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Extras'
|
||||
|
||||
|
||||
#
|
||||
# Custom field choices
|
||||
#
|
||||
|
@ -1,18 +1,9 @@
|
||||
from rest_framework import routers
|
||||
|
||||
from utilities.api import OrderedDefaultRouter
|
||||
from . import views
|
||||
|
||||
|
||||
class IPAMRootView(routers.APIRootView):
|
||||
"""
|
||||
IPAM API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'IPAM'
|
||||
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.APIRootView = IPAMRootView
|
||||
router = OrderedDefaultRouter()
|
||||
router.APIRootView = views.IPAMRootView
|
||||
|
||||
# VRFs
|
||||
router.register('vrfs', views.VRFViewSet)
|
||||
|
@ -1,11 +1,12 @@
|
||||
from django.conf import settings
|
||||
from django.db.models import Count, Prefetch
|
||||
from django.db.models import Count
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django_pglocks import advisory_lock
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.routers import APIRootView
|
||||
|
||||
from extras.api.views import CustomFieldModelViewSet
|
||||
from ipam import filters
|
||||
@ -16,6 +17,14 @@ from utilities.utils import get_subquery
|
||||
from . import serializers
|
||||
|
||||
|
||||
class IPAMRootView(APIRootView):
|
||||
"""
|
||||
IPAM API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'IPAM'
|
||||
|
||||
|
||||
#
|
||||
# VRFs
|
||||
#
|
||||
|
@ -1,18 +1,9 @@
|
||||
from rest_framework import routers
|
||||
|
||||
from utilities.api import OrderedDefaultRouter
|
||||
from . import views
|
||||
|
||||
|
||||
class SecretsRootView(routers.APIRootView):
|
||||
"""
|
||||
Secrets API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Secrets'
|
||||
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.APIRootView = SecretsRootView
|
||||
router = OrderedDefaultRouter()
|
||||
router.APIRootView = views.SecretsRootView
|
||||
|
||||
# Secrets
|
||||
router.register('secret-roles', views.SecretRoleViewSet)
|
||||
|
@ -6,6 +6,7 @@ from django.http import HttpResponseBadRequest
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.routers import APIRootView
|
||||
from rest_framework.viewsets import ViewSet
|
||||
|
||||
from secrets import filters
|
||||
@ -20,6 +21,14 @@ ERR_PRIVKEY_MISSING = "Private key was not provided."
|
||||
ERR_PRIVKEY_INVALID = "Invalid private key."
|
||||
|
||||
|
||||
class SecretsRootView(APIRootView):
|
||||
"""
|
||||
Secrets API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Secrets'
|
||||
|
||||
|
||||
#
|
||||
# Secret Roles
|
||||
#
|
||||
|
@ -1,18 +1,9 @@
|
||||
from rest_framework import routers
|
||||
|
||||
from utilities.api import OrderedDefaultRouter
|
||||
from . import views
|
||||
|
||||
|
||||
class TenancyRootView(routers.APIRootView):
|
||||
"""
|
||||
Tenancy API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Tenancy'
|
||||
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.APIRootView = TenancyRootView
|
||||
router = OrderedDefaultRouter()
|
||||
router.APIRootView = views.TenancyRootView
|
||||
|
||||
# Tenants
|
||||
router.register('tenant-groups', views.TenantGroupViewSet)
|
||||
|
@ -1,3 +1,5 @@
|
||||
from rest_framework.routers import APIRootView
|
||||
|
||||
from circuits.models import Circuit
|
||||
from dcim.models import Device, Rack, Site
|
||||
from extras.api.views import CustomFieldModelViewSet
|
||||
@ -10,6 +12,14 @@ from virtualization.models import VirtualMachine
|
||||
from . import serializers
|
||||
|
||||
|
||||
class TenancyRootView(APIRootView):
|
||||
"""
|
||||
Tenancy API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Tenancy'
|
||||
|
||||
|
||||
#
|
||||
# Tenant Groups
|
||||
#
|
||||
|
@ -1,18 +1,9 @@
|
||||
from rest_framework import routers
|
||||
|
||||
from utilities.api import OrderedDefaultRouter
|
||||
from . import views
|
||||
|
||||
|
||||
class UsersRootView(routers.APIRootView):
|
||||
"""
|
||||
Users API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Users'
|
||||
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.APIRootView = UsersRootView
|
||||
router = OrderedDefaultRouter()
|
||||
router.APIRootView = views.UsersRootView
|
||||
|
||||
# Users and groups
|
||||
router.register('users', views.UserViewSet)
|
||||
|
@ -1,5 +1,6 @@
|
||||
from django.contrib.auth.models import Group, User
|
||||
from django.db.models import Count
|
||||
from rest_framework.routers import APIRootView
|
||||
|
||||
from users import filters
|
||||
from users.models import ObjectPermission
|
||||
@ -8,6 +9,14 @@ from utilities.querysets import RestrictedQuerySet
|
||||
from . import serializers
|
||||
|
||||
|
||||
class UsersRootView(APIRootView):
|
||||
"""
|
||||
Users API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Users'
|
||||
|
||||
|
||||
#
|
||||
# Users and groups
|
||||
#
|
||||
|
@ -13,6 +13,7 @@ from rest_framework.exceptions import APIException, ValidationError
|
||||
from rest_framework.permissions import BasePermission
|
||||
from rest_framework.relations import PrimaryKeyRelatedField, RelatedField
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from rest_framework.viewsets import ModelViewSet as _ModelViewSet
|
||||
|
||||
from .utils import dict_to_filter_params, dynamic_import
|
||||
@ -399,3 +400,21 @@ class ModelViewSet(_ModelViewSet):
|
||||
logger.info(f"Deleting {model._meta.verbose_name} {instance} (PK: {instance.pk})")
|
||||
|
||||
return super().perform_destroy(instance)
|
||||
|
||||
|
||||
#
|
||||
# Routers
|
||||
#
|
||||
|
||||
class OrderedDefaultRouter(DefaultRouter):
|
||||
|
||||
def get_api_root_view(self, api_urls=None):
|
||||
"""
|
||||
Wrap DRF's DefaultRouter to return an alphabetized list of endpoints.
|
||||
"""
|
||||
api_root_dict = OrderedDict()
|
||||
list_name = self.routes[0].name
|
||||
for prefix, viewset, basename in sorted(self.registry, key=lambda x: x[0]):
|
||||
api_root_dict[prefix] = list_name.format(basename=basename)
|
||||
|
||||
return self.APIRootView.as_view(api_root_dict=api_root_dict)
|
||||
|
@ -1,18 +1,9 @@
|
||||
from rest_framework import routers
|
||||
|
||||
from utilities.api import OrderedDefaultRouter
|
||||
from . import views
|
||||
|
||||
|
||||
class VirtualizationRootView(routers.APIRootView):
|
||||
"""
|
||||
Virtualization API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Virtualization'
|
||||
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.APIRootView = VirtualizationRootView
|
||||
router = OrderedDefaultRouter()
|
||||
router.APIRootView = views.VirtualizationRootView
|
||||
|
||||
# Clusters
|
||||
router.register('cluster-types', views.ClusterTypeViewSet)
|
||||
|
@ -2,6 +2,7 @@ from django.db.models import Count
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.routers import APIRootView
|
||||
|
||||
from dcim.models import Device
|
||||
from extras.api.serializers import RenderedGraphSerializer
|
||||
@ -14,6 +15,14 @@ from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMac
|
||||
from . import serializers
|
||||
|
||||
|
||||
class VirtualizationRootView(APIRootView):
|
||||
"""
|
||||
Virtualization API root view
|
||||
"""
|
||||
def get_view_name(self):
|
||||
return 'Virtualization'
|
||||
|
||||
|
||||
#
|
||||
# Clusters
|
||||
#
|
||||
|
Reference in New Issue
Block a user