diff --git a/netbox/circuits/api/urls.py b/netbox/circuits/api/urls.py index 0dd2d2a94..f06b14165 100644 --- a/netbox/circuits/api/urls.py +++ b/netbox/circuits/api/urls.py @@ -18,10 +18,6 @@ urlpatterns = [ url(r'', include(router.urls)), - # Providers - url(r'^providers/(?P\d+)/graphs/$', GraphListView.as_view(), {'type': GRAPH_TYPE_PROVIDER}, - name='provider_graphs'), - # Circuits url(r'^circuits/(?P\d+)/terminations/$', views.NestedCircuitTerminationViewSet.as_view({'get': 'list'})), diff --git a/netbox/circuits/api/views.py b/netbox/circuits/api/views.py index ccfe57a4c..1fdafa97b 100644 --- a/netbox/circuits/api/views.py +++ b/netbox/circuits/api/views.py @@ -1,13 +1,17 @@ from django.shortcuts import get_object_or_404 +from rest_framework.decorators import detail_route from rest_framework.mixins import ( CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, ) +from rest_framework.response import Response from rest_framework.viewsets import GenericViewSet, ModelViewSet from circuits.models import Provider, CircuitTermination, CircuitType, Circuit from circuits.filters import CircuitFilter +from extras.models import Graph, GRAPH_TYPE_PROVIDER +from extras.api.serializers import GraphSerializer from extras.api.views import CustomFieldModelViewSet from utilities.api import WritableSerializerMixin from . import serializers @@ -21,6 +25,13 @@ class ProviderViewSet(CustomFieldModelViewSet): queryset = Provider.objects.all() serializer_class = serializers.ProviderSerializer + @detail_route() + def graphs(self, request, pk=None): + provider = get_object_or_404(Provider, pk=pk) + queryset = Graph.objects.filter(type=GRAPH_TYPE_PROVIDER) + serializer = GraphSerializer(queryset, many=True, context={'graphed_object': provider}) + return Response(serializer.data) + # # Circuit Types diff --git a/netbox/dcim/api/urls.py b/netbox/dcim/api/urls.py index a7c17b368..27f3813f2 100644 --- a/netbox/dcim/api/urls.py +++ b/netbox/dcim/api/urls.py @@ -37,6 +37,8 @@ router.register(r'device-bays', views.DeviceBayViewSet) router.register(r'modules', views.ModuleViewSet) router.register(r'services', ServiceViewSet) +# TODO: Device type components + # Device components device_router = routers.DefaultRouter() device_router.register(r'console-ports', views.DeviceConsolePortViewSet, base_name='consoleport') @@ -53,22 +55,12 @@ urlpatterns = [ url(r'', include(router.urls)), url(r'^devices/(?P\d+)/', include(device_router.urls)), - # Sites - url(r'^sites/(?P\d+)/graphs/$', GraphListView.as_view(), {'type': GRAPH_TYPE_SITE}, name='site_graphs'), - # Racks url(r'^racks/(?P\d+)/rack-units/$', views.RackUnitListView.as_view(), name='rack_units'), - # Device types - # TODO: Nested DeviceType components - # Devices url(r'^devices/(?P\d+)/lldp-neighbors/$', views.LLDPNeighborsView.as_view(), name='device_lldp-neighbors'), - # Interfaces - url(r'^interfaces/(?P\d+)/graphs/$', GraphListView.as_view(), {'type': GRAPH_TYPE_INTERFACE}, - name='interface_graphs'), - # Miscellaneous url(r'^related-connections/$', views.RelatedConnectionsView.as_view(), name='related_connections'), url(r'^topology-maps/(?P[\w-]+)/$', TopologyMapView.as_view(), name='topology_map'), diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index 472fc6931..696b306aa 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -1,3 +1,4 @@ +from rest_framework.decorators import detail_route from rest_framework.mixins import ( CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, ) @@ -16,8 +17,10 @@ from dcim.models import ( Manufacturer, Module, Platform, PowerOutlet, PowerPort, Rack, RackGroup, RackRole, Site, ) from dcim import filters -from extras.api.views import CustomFieldModelViewSet from extras.api.renderers import BINDZoneRenderer, FlatJSONRenderer +from extras.api.serializers import GraphSerializer +from extras.api.views import CustomFieldModelViewSet +from extras.models import Graph, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE from utilities.api import ServiceUnavailable, WritableSerializerMixin from .exceptions import MissingFilterException from . import serializers @@ -31,6 +34,13 @@ class SiteViewSet(WritableSerializerMixin, CustomFieldModelViewSet): queryset = Site.objects.select_related('tenant') serializer_class = serializers.SiteSerializer + @detail_route() + def graphs(self, request, pk=None): + site = get_object_or_404(Site, pk=pk) + queryset = Graph.objects.filter(type=GRAPH_TYPE_SITE) + serializer = GraphSerializer(queryset, many=True, context={'graphed_object': site}) + return Response(serializer.data) + # # Rack groups @@ -221,6 +231,13 @@ class InterfaceViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, queryset = Interface.objects.select_related('device') serializer_class = serializers.InterfaceSerializer + @detail_route() + def graphs(self, request, pk=None): + interface = get_object_or_404(Interface, pk=pk) + queryset = Graph.objects.filter(type=GRAPH_TYPE_INTERFACE) + serializer = GraphSerializer(queryset, many=True, context={'graphed_object': interface}) + return Response(serializer.data) + class DeviceInterfaceViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): serializer_class = serializers.DeviceInterfaceSerializer @@ -272,7 +289,7 @@ class DeviceModuleViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMi # class InterfaceConnectionViewSet(ModelViewSet): - queryset = InterfaceConnection.objects.all() + queryset = InterfaceConnection.objects.select_related('interface_a__device', 'interface_b__device') serializer_class = serializers.InterfaceConnectionSerializer