From 406708218bf41d5fb72db814399b2011d9e48856 Mon Sep 17 00:00:00 2001 From: Dan Starner Date: Mon, 2 Mar 2020 13:34:01 -0500 Subject: [PATCH 1/3] set local_context_data serializer on device and vm to method --- netbox/dcim/api/serializers.py | 6 ++++++ netbox/virtualization/api/serializers.py | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 5483904f5..7a7feb8e1 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -376,6 +376,7 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer): cluster = NestedClusterSerializer(required=False, allow_null=True) virtual_chassis = NestedVirtualChassisSerializer(required=False, allow_null=True) tags = TagListSerializerField(required=False) + local_context_data = serializers.SerializerMethodField() class Meta: model = Device @@ -411,6 +412,11 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer): data['device_bay'] = NestedDeviceBaySerializer(instance=device_bay, context=context).data return data + @swagger_serializer_method(serializer_or_field=serializers.DictField) + def get_local_context_data(self, obj): + """Used to strongly type the local_context_data field for Swagger generation + """ + return obj.local_context_data class DeviceWithConfigContextSerializer(DeviceSerializer): config_context = serializers.SerializerMethodField() diff --git a/netbox/virtualization/api/serializers.py b/netbox/virtualization/api/serializers.py index a294cdb6f..ecddfbdae 100644 --- a/netbox/virtualization/api/serializers.py +++ b/netbox/virtualization/api/serializers.py @@ -67,6 +67,7 @@ class VirtualMachineSerializer(TaggitSerializer, CustomFieldModelSerializer): primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True) primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True) tags = TagListSerializerField(required=False) + local_context_data = serializers.SerializerMethodField() class Meta: model = VirtualMachine @@ -77,6 +78,12 @@ class VirtualMachineSerializer(TaggitSerializer, CustomFieldModelSerializer): ] validators = [] + @swagger_serializer_method(serializer_or_field=serializers.DictField) + def get_local_context_data(self, obj): + """Used to strongly type the local_context_data field for Swagger generation + """ + return obj.local_context_data + class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer): config_context = serializers.SerializerMethodField() From 3070c7e9911568637bc0a9a8ca8ea777dcb14425 Mon Sep 17 00:00:00 2001 From: Daniel Starner Date: Mon, 2 Mar 2020 15:45:58 -0500 Subject: [PATCH 2/3] fix linting mistake --- netbox/dcim/api/serializers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 7a7feb8e1..03cf8dde3 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -418,6 +418,7 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer): """ return obj.local_context_data + class DeviceWithConfigContextSerializer(DeviceSerializer): config_context = serializers.SerializerMethodField() From e6ee9803d49276b5a31ae6d977b32fb4cd486a27 Mon Sep 17 00:00:00 2001 From: Dan Starner Date: Tue, 3 Mar 2020 12:04:46 -0500 Subject: [PATCH 3/3] use FieldInspector for JSONField type --- netbox/dcim/api/serializers.py | 7 ------- netbox/netbox/settings.py | 1 + netbox/utilities/custom_inspectors.py | 10 ++++++++++ netbox/virtualization/api/serializers.py | 7 ------- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 03cf8dde3..5483904f5 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -376,7 +376,6 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer): cluster = NestedClusterSerializer(required=False, allow_null=True) virtual_chassis = NestedVirtualChassisSerializer(required=False, allow_null=True) tags = TagListSerializerField(required=False) - local_context_data = serializers.SerializerMethodField() class Meta: model = Device @@ -412,12 +411,6 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer): data['device_bay'] = NestedDeviceBaySerializer(instance=device_bay, context=context).data return data - @swagger_serializer_method(serializer_or_field=serializers.DictField) - def get_local_context_data(self, obj): - """Used to strongly type the local_context_data field for Swagger generation - """ - return obj.local_context_data - class DeviceWithConfigContextSerializer(DeviceSerializer): config_context = serializers.SerializerMethodField() diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 89958bc13..7f4f44b1a 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -506,6 +506,7 @@ REST_FRAMEWORK = { SWAGGER_SETTINGS = { 'DEFAULT_AUTO_SCHEMA_CLASS': 'utilities.custom_inspectors.NetBoxSwaggerAutoSchema', 'DEFAULT_FIELD_INSPECTORS': [ + 'utilities.custom_inspectors.JSONFieldInspector', 'utilities.custom_inspectors.NullableBooleanFieldInspector', 'utilities.custom_inspectors.CustomChoiceFieldInspector', 'utilities.custom_inspectors.TagListFieldInspector', diff --git a/netbox/utilities/custom_inspectors.py b/netbox/utilities/custom_inspectors.py index 3eaf1ccf1..68fe57d82 100644 --- a/netbox/utilities/custom_inspectors.py +++ b/netbox/utilities/custom_inspectors.py @@ -1,3 +1,4 @@ +from django.contrib.postgres.fields import JSONField from drf_yasg import openapi from drf_yasg.inspectors import FieldInspector, NotHandled, PaginatorInspector, FilterInspector, SwaggerAutoSchema from drf_yasg.utils import get_serializer_ref_name @@ -119,6 +120,15 @@ class NullableBooleanFieldInspector(FieldInspector): return result +class JSONFieldInspector(FieldInspector): + """Required because by default, Swagger sees a JSONField as a string and not dict + """ + def process_result(self, result, method_name, obj, **kwargs): + if isinstance(result, openapi.Schema) and isinstance(obj, JSONField): + result.type = 'dict' + return result + + class IdInFilterInspector(FilterInspector): def process_result(self, result, method_name, obj, **kwargs): if isinstance(result, list): diff --git a/netbox/virtualization/api/serializers.py b/netbox/virtualization/api/serializers.py index ecddfbdae..a294cdb6f 100644 --- a/netbox/virtualization/api/serializers.py +++ b/netbox/virtualization/api/serializers.py @@ -67,7 +67,6 @@ class VirtualMachineSerializer(TaggitSerializer, CustomFieldModelSerializer): primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True) primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True) tags = TagListSerializerField(required=False) - local_context_data = serializers.SerializerMethodField() class Meta: model = VirtualMachine @@ -78,12 +77,6 @@ class VirtualMachineSerializer(TaggitSerializer, CustomFieldModelSerializer): ] validators = [] - @swagger_serializer_method(serializer_or_field=serializers.DictField) - def get_local_context_data(self, obj): - """Used to strongly type the local_context_data field for Swagger generation - """ - return obj.local_context_data - class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer): config_context = serializers.SerializerMethodField()