diff --git a/netbox/dcim/apps.py b/netbox/dcim/apps.py index bfb09e601..d9b45ae3f 100644 --- a/netbox/dcim/apps.py +++ b/netbox/dcim/apps.py @@ -10,6 +10,7 @@ class DCIMConfig(AppConfig): def ready(self): from . import signals, search from .models import CableTermination + from . import schema # noqa: E402 # Register denormalized fields denormalized.register(CableTermination, '_device', { diff --git a/netbox/dcim/schema.py b/netbox/dcim/schema.py new file mode 100644 index 000000000..47b3ba832 --- /dev/null +++ b/netbox/dcim/schema.py @@ -0,0 +1,14 @@ +from drf_spectacular.extensions import ( + OpenApiSerializerFieldExtension +) +from drf_spectacular.extensions import OpenApiViewExtension +from drf_spectacular.utils import extend_schema +from drf_spectacular.plumbing import build_basic_type +from drf_spectacular.types import OpenApiTypes + + +class FixTimeZoneSerializerField(OpenApiSerializerFieldExtension): + target_class = 'timezone_field.rest_framework.TimeZoneSerializerField' + + def map_serializer_field(self, auto_schema, direction): + return build_basic_type(OpenApiTypes.STR) diff --git a/netbox/extras/api/customfields.py b/netbox/extras/api/customfields.py index d16fc0daf..ce3b388f4 100644 --- a/netbox/extras/api/customfields.py +++ b/netbox/extras/api/customfields.py @@ -1,4 +1,6 @@ from django.contrib.contenttypes.models import ContentType +from drf_spectacular.utils import extend_schema_field +from drf_spectacular.types import OpenApiTypes from rest_framework.fields import Field from rest_framework.serializers import ValidationError @@ -36,6 +38,7 @@ class CustomFieldDefaultValues: return value +@extend_schema_field(OpenApiTypes.OBJECT) class CustomFieldsDataField(Field): def _get_custom_fields(self): diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index d0ff6f511..5e66ffee3 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -9,6 +9,7 @@ from dcim.api.nested_serializers import ( ) from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup from drf_spectacular.utils import extend_schema_field +from drf_spectacular.types import OpenApiTypes from extras.choices import * from extras.models import * from extras.utils import FeatureQuery @@ -97,6 +98,7 @@ class CustomFieldSerializer(ValidatedModelSerializer): 'validation_minimum', 'validation_maximum', 'validation_regex', 'choices', 'created', 'last_updated', ] + @extend_schema_field(OpenApiTypes.STR) def get_data_type(self, obj): types = CustomFieldTypeChoices if obj.type == types.TYPE_INTEGER: diff --git a/netbox/ipam/fields.py b/netbox/ipam/fields.py index 7d28127a4..968d31d6d 100644 --- a/netbox/ipam/fields.py +++ b/netbox/ipam/fields.py @@ -1,11 +1,14 @@ from django.core.exceptions import ValidationError from django.db import models +from drf_spectacular.utils import extend_schema_field +from drf_spectacular.types import OpenApiTypes from netaddr import AddrFormatError, IPNetwork from . import lookups, validators from .formfields import IPNetworkFormField +@extend_schema_field(OpenApiTypes.STR) class BaseIPField(models.Field): def python_type(self): @@ -67,6 +70,7 @@ IPNetworkField.register_lookup(lookups.NetFamily) IPNetworkField.register_lookup(lookups.NetMaskLength) +@extend_schema_field(OpenApiTypes.STR) class IPAddressField(BaseIPField): """ IP address (host address and mask) diff --git a/netbox/netbox/api/fields.py b/netbox/netbox/api/fields.py index 52343c2f6..19974a172 100644 --- a/netbox/netbox/api/fields.py +++ b/netbox/netbox/api/fields.py @@ -1,4 +1,6 @@ from django.core.exceptions import ObjectDoesNotExist +from drf_spectacular.utils import extend_schema_field +from drf_spectacular.types import OpenApiTypes from netaddr import IPNetwork from rest_framework import serializers from rest_framework.exceptions import ValidationError @@ -12,6 +14,7 @@ __all__ = ( ) +@extend_schema_field(OpenApiTypes.OBJECT) class ChoiceField(serializers.Field): """ Represent a ChoiceField as {'value': , 'label': }. Accepts a single value on write. @@ -86,6 +89,7 @@ class ChoiceField(serializers.Field): return self._choices +@extend_schema_field(OpenApiTypes.STR) class ContentTypeField(RelatedField): """ Represent a ContentType as '.' diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index fe2b5cf38..224d3617b 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -578,6 +578,7 @@ SPECTACULAR_SETTINGS = { "DESCRIPTION": "API to access NetBox", "LICENSE": {"name": "Apache v2 License"}, "VERSION": VERSION, + 'COMPONENT_SPLIT_REQUEST': True, } #