diff --git a/netbox/core/api/schema.py b/netbox/core/api/schema.py index 0b44a3d52..1502592b0 100644 --- a/netbox/core/api/schema.py +++ b/netbox/core/api/schema.py @@ -10,6 +10,7 @@ from drf_spectacular.plumbing import ( ComponentRegistry, ResolvedComponent, build_basic_type, + build_choice_field, build_media_type_object, build_object_type, is_serializer, @@ -38,7 +39,7 @@ class ChoiceFieldFix(OpenApiSerializerFieldExtension): def map_serializer_field(self, auto_schema, direction): if direction == 'request': - return build_basic_type(OpenApiTypes.STR) + return build_choice_field(self.target) elif direction == "response": return build_object_type( @@ -150,8 +151,12 @@ class NetBoxAutoSchema(AutoSchema): def get_writable_class(self, serializer): properties = {} fields = {} if hasattr(serializer, 'child') else serializer.fields + remove_fields = [] for child_name, child in fields.items(): + # read_only fields don't need to be in writable (write only) serializers + if 'read_only' in dir(child) and child.read_only: + remove_fields.append(child_name) if isinstance(child, (ChoiceField, WritableNestedSerializer)): properties[child_name] = None elif isinstance(child, ManyRelatedField) and isinstance(child.child_relation, SerializedPKRelatedField): @@ -165,7 +170,12 @@ class NetBoxAutoSchema(AutoSchema): meta_class = getattr(type(serializer), 'Meta', None) if meta_class: ref_name = 'Writable' + self.get_serializer_ref_name(serializer) - writable_meta = type('Meta', (meta_class,), {'ref_name': ref_name}) + # remove read_only fields from write-only serializers + fields = list(meta_class.fields) + for field in remove_fields: + fields.remove(field) + writable_meta = type('Meta', (meta_class,), {'ref_name': ref_name, 'fields': fields}) + properties['Meta'] = writable_meta self.writable_serializers[type(serializer)] = type(writable_name, (type(serializer),), properties) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 6a9b8189e..2745a22b8 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -587,9 +587,10 @@ SPECTACULAR_SETTINGS = { 'VERSION': VERSION, 'COMPONENT_SPLIT_REQUEST': True, 'REDOC_DIST': 'SIDECAR', - 'SERVERS': [{'url': f'/{BASE_PATH}api'}, ], + 'SERVERS': [{'url': f'/{BASE_PATH}api'}], 'SWAGGER_UI_DIST': 'SIDECAR', 'SWAGGER_UI_FAVICON_HREF': 'SIDECAR', + 'POSTPROCESSING_HOOKS': [], } #