From 8f5543fe88dc965626417e14fd46eeba37cbe29c Mon Sep 17 00:00:00 2001 From: Zach Moody Date: Mon, 7 Mar 2016 23:57:49 -0600 Subject: [PATCH 1/2] dcim: added json flat renderer. --- netbox/dcim/api/views.py | 4 +-- netbox/dcim/tests/test_apis.py | 50 ++++++++++++++++++++++++++++++++++ netbox/extras/api/renderers.py | 22 ++++++++++++++- 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index c2e1c5e16..839d23d7c 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -16,7 +16,7 @@ from .serializers import SiteSerializer, RackGroupSerializer, RackSerializer, Ra ManufacturerSerializer, DeviceTypeSerializer, DeviceRoleSerializer, PlatformSerializer, DeviceSerializer, \ DeviceNestedSerializer, ConsolePortSerializer, ConsoleServerPortSerializer, PowerPortSerializer, \ PowerOutletSerializer, InterfaceSerializer, InterfaceDetailSerializer, InterfaceConnectionSerializer -from extras.api.renderers import BINDZoneRenderer +from extras.api.renderers import BINDZoneRenderer, FlatJSONRenderer from utilities.api import ServiceUnavailable @@ -198,7 +198,7 @@ class DeviceListView(generics.ListAPIView): .prefetch_related('primary_ip__nat_outside') serializer_class = DeviceSerializer filter_class = DeviceFilter - renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES + [BINDZoneRenderer] + renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES + [BINDZoneRenderer, FlatJSONRenderer] class DeviceDetailView(generics.RetrieveAPIView): diff --git a/netbox/dcim/tests/test_apis.py b/netbox/dcim/tests/test_apis.py index b6bd72051..a99f8bf88 100644 --- a/netbox/dcim/tests/test_apis.py +++ b/netbox/dcim/tests/test_apis.py @@ -322,6 +322,14 @@ class DeviceTest(APITestCase): nested_fields = ['id', 'name'] + # Holds primary IP nested fields until api tests + # can be made and fields imported. + primary_ip = [ + 'id', + 'family', + 'address' + ] + def test_get_list(self, endpoint='/api/dcim/devices/'): response = self.client.get(endpoint) content = json.loads(response.content) @@ -349,6 +357,48 @@ class DeviceTest(APITestCase): sorted(RackTest.nested_fields), ) + def test_get_list_flat(self, endpoint='/api/dcim/devices/?format=json_flat'): + + flat_fields = [ + 'comments', + 'device_role_id', + 'device_role_name', + 'device_role_slug', + 'device_type_id', + 'device_type_manufacturer_id', + 'device_type_manufacturer_name', + 'device_type_manufacturer_slug', + 'device_type_model', + 'device_type_slug', + 'display_name', + 'face', + 'id', + 'name', + 'platform_id', + 'platform_name', + 'platform_slug', + 'position', + 'primary_ip_address', + 'primary_ip_family', + 'primary_ip_id', + 'rack_display_name', + 'rack_facility_id', + 'rack_id', + 'rack_name', + 'ro_snmp', + 'serial', + 'status', + ] + + response = self.client.get(endpoint) + content = json.loads(response.content) + self.assertEqual(response.status_code, status.HTTP_200_OK) + device = content[0] + self.assertEqual( + sorted(device.keys()), + sorted(flat_fields), + ) + def test_get_detail(self, endpoint='/api/dcim/devices/1/'): response = self.client.get(endpoint) content = json.loads(response.content) diff --git a/netbox/extras/api/renderers.py b/netbox/extras/api/renderers.py index 0a464c3b1..e557928bd 100644 --- a/netbox/extras/api/renderers.py +++ b/netbox/extras/api/renderers.py @@ -1,6 +1,6 @@ +import json from rest_framework import renderers - # IP address family designations AF = { 4: 'A', @@ -29,3 +29,23 @@ class BINDZoneRenderer(renderers.BaseRenderer): except KeyError: pass return '\n'.join(records) + + +class FlatJSONRenderer(renderers.BaseRenderer): + """ + Flattens a nested JSON reponse. + """ + format = 'json_flat' + media_type = 'application/json' + + def render(self, data, media_type=None, renderer_context=None): + + def flatten(entry): + for key, val in entry.iteritems(): + if isinstance(val, dict): + for child_key, child_val in flatten(val): + yield "{}_{}".format(key, child_key), child_val + else: + yield key, val + + return json.dumps([dict(flatten(i)) for i in data]) From 01d0ba7ee1aaae2d9fa946a74dbb2ee79af34c45 Mon Sep 17 00:00:00 2001 From: Zach Moody Date: Tue, 8 Mar 2016 12:46:05 -0600 Subject: [PATCH 2/2] dcim: removed unneeded primary_ip list --- netbox/dcim/tests/test_apis.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/netbox/dcim/tests/test_apis.py b/netbox/dcim/tests/test_apis.py index a99f8bf88..45d6dd2f0 100644 --- a/netbox/dcim/tests/test_apis.py +++ b/netbox/dcim/tests/test_apis.py @@ -322,14 +322,6 @@ class DeviceTest(APITestCase): nested_fields = ['id', 'name'] - # Holds primary IP nested fields until api tests - # can be made and fields imported. - primary_ip = [ - 'id', - 'family', - 'address' - ] - def test_get_list(self, endpoint='/api/dcim/devices/'): response = self.client.get(endpoint) content = json.loads(response.content)