1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #9608: Move from drf-yasg to spectacular

Co-authored-by: arthanson <worldnomad@gmail.com>
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
This commit is contained in:
Arthur Hanson
2023-03-30 11:32:59 -07:00
committed by GitHub
parent 1be626e5ee
commit ecd0c56554
35 changed files with 514 additions and 340 deletions

View File

@@ -2,7 +2,8 @@ import decimal
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import gettext as _
from drf_yasg.utils import swagger_serializer_method
from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes
from rest_framework import serializers
from timezone_field.rest_framework import TimeZoneSerializerField
@@ -33,12 +34,13 @@ from .nested_serializers import *
class CabledObjectSerializer(serializers.ModelSerializer):
cable = NestedCableSerializer(read_only=True)
cable = NestedCableSerializer(read_only=True, allow_null=True)
cable_end = serializers.CharField(read_only=True)
link_peers_type = serializers.SerializerMethodField(read_only=True)
link_peers = serializers.SerializerMethodField(read_only=True)
_occupied = serializers.SerializerMethodField(read_only=True)
@extend_schema_field(OpenApiTypes.STR)
def get_link_peers_type(self, obj):
"""
Return the type of the peer link terminations, or None.
@@ -51,7 +53,7 @@ class CabledObjectSerializer(serializers.ModelSerializer):
return None
@swagger_serializer_method(serializer_or_field=serializers.ListField)
@extend_schema_field(serializers.ListField)
def get_link_peers(self, obj):
"""
Return the appropriate serializer for the link termination model.
@@ -64,7 +66,7 @@ class CabledObjectSerializer(serializers.ModelSerializer):
context = {'request': self.context['request']}
return serializer(obj.link_peers, context=context, many=True).data
@swagger_serializer_method(serializer_or_field=serializers.BooleanField)
@extend_schema_field(serializers.BooleanField)
def get__occupied(self, obj):
return obj._occupied
@@ -77,11 +79,12 @@ class ConnectedEndpointsSerializer(serializers.ModelSerializer):
connected_endpoints = serializers.SerializerMethodField(read_only=True)
connected_endpoints_reachable = serializers.SerializerMethodField(read_only=True)
@extend_schema_field(OpenApiTypes.STR)
def get_connected_endpoints_type(self, obj):
if endpoints := obj.connected_endpoints:
return f'{endpoints[0]._meta.app_label}.{endpoints[0]._meta.model_name}'
@swagger_serializer_method(serializer_or_field=serializers.ListField)
@extend_schema_field(serializers.ListField)
def get_connected_endpoints(self, obj):
"""
Return the appropriate serializer for the type of connected object.
@@ -91,7 +94,7 @@ class ConnectedEndpointsSerializer(serializers.ModelSerializer):
context = {'request': self.context['request']}
return serializer(endpoints, many=True, context=context).data
@swagger_serializer_method(serializer_or_field=serializers.BooleanField)
@extend_schema_field(serializers.BooleanField)
def get_connected_endpoints_reachable(self, obj):
return obj._path and obj._path.is_complete and obj._path.is_active
@@ -198,12 +201,12 @@ class RackSerializer(NetBoxModelSerializer):
tenant = NestedTenantSerializer(required=False, allow_null=True)
status = ChoiceField(choices=RackStatusChoices, required=False)
role = NestedRackRoleSerializer(required=False, allow_null=True)
type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False)
type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False, allow_null=True)
facility_id = serializers.CharField(max_length=50, allow_blank=True, allow_null=True, label=_('Facility ID'),
default=None)
width = ChoiceField(choices=RackWidthChoices, required=False)
outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False)
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False)
outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False, allow_null=True)
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False, allow_null=True)
device_count = serializers.IntegerField(read_only=True)
powerfeed_count = serializers.IntegerField(read_only=True)
@@ -232,6 +235,7 @@ class RackUnitSerializer(serializers.Serializer):
occupied = serializers.BooleanField(read_only=True)
display = serializers.SerializerMethodField(read_only=True)
@extend_schema_field(OpenApiTypes.STR)
def get_display(self, obj):
return obj['name']
@@ -318,9 +322,9 @@ class DeviceTypeSerializer(NetBoxModelSerializer):
min_value=0,
default=1.0
)
subdevice_role = ChoiceField(choices=SubdeviceRoleChoices, allow_blank=True, required=False)
airflow = ChoiceField(choices=DeviceAirflowChoices, allow_blank=True, required=False)
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False)
subdevice_role = ChoiceField(choices=SubdeviceRoleChoices, allow_blank=True, required=False, allow_null=True)
airflow = ChoiceField(choices=DeviceAirflowChoices, allow_blank=True, required=False, allow_null=True)
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False, allow_null=True)
device_count = serializers.IntegerField(read_only=True)
class Meta:
@@ -335,7 +339,7 @@ class DeviceTypeSerializer(NetBoxModelSerializer):
class ModuleTypeSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:moduletype-detail')
manufacturer = NestedManufacturerSerializer()
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False)
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False, allow_null=True)
class Meta:
model = ModuleType
@@ -416,7 +420,8 @@ class PowerPortTemplateSerializer(ValidatedModelSerializer):
type = ChoiceField(
choices=PowerPortTypeChoices,
allow_blank=True,
required=False
required=False,
allow_null=True
)
class Meta:
@@ -442,7 +447,8 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer):
type = ChoiceField(
choices=PowerOutletTypeChoices,
allow_blank=True,
required=False
required=False,
allow_null=True
)
power_port = NestedPowerPortTemplateSerializer(
required=False,
@@ -451,7 +457,8 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer):
feed_leg = ChoiceField(
choices=PowerOutletFeedLegChoices,
allow_blank=True,
required=False
required=False,
allow_null=True
)
class Meta:
@@ -482,12 +489,14 @@ class InterfaceTemplateSerializer(ValidatedModelSerializer):
poe_mode = ChoiceField(
choices=InterfacePoEModeChoices,
required=False,
allow_blank=True
allow_blank=True,
allow_null=True
)
poe_type = ChoiceField(
choices=InterfacePoETypeChoices,
required=False,
allow_blank=True
allow_blank=True,
allow_null=True
)
class Meta:
@@ -589,7 +598,7 @@ class InventoryItemTemplateSerializer(ValidatedModelSerializer):
'description', 'component_type', 'component_id', 'component', 'created', 'last_updated', '_depth',
]
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_component(self, obj):
if obj.component is None:
return None
@@ -640,7 +649,7 @@ class DeviceSerializer(NetBoxModelSerializer):
site = NestedSiteSerializer()
location = NestedLocationSerializer(required=False, allow_null=True, default=None)
rack = NestedRackSerializer(required=False, allow_null=True, default=None)
face = ChoiceField(choices=DeviceFaceChoices, allow_blank=True, default='')
face = ChoiceField(choices=DeviceFaceChoices, allow_blank=True, default=lambda: '')
position = serializers.DecimalField(
max_digits=4,
decimal_places=1,
@@ -669,7 +678,7 @@ class DeviceSerializer(NetBoxModelSerializer):
'comments', 'config_template', 'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
]
@swagger_serializer_method(serializer_or_field=NestedDeviceSerializer)
@extend_schema_field(NestedDeviceSerializer)
def get_parent_device(self, obj):
try:
device_bay = obj.parent_bay
@@ -682,7 +691,7 @@ class DeviceSerializer(NetBoxModelSerializer):
class DeviceWithConfigContextSerializer(DeviceSerializer):
config_context = serializers.SerializerMethodField()
config_context = serializers.SerializerMethodField(read_only=True)
class Meta(DeviceSerializer.Meta):
fields = [
@@ -692,7 +701,7 @@ class DeviceWithConfigContextSerializer(DeviceSerializer):
'comments', 'local_context_data', 'tags', 'custom_fields', 'config_context', 'created', 'last_updated',
]
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_config_context(self, obj):
return obj.get_config_context()
@@ -701,7 +710,7 @@ class VirtualDeviceContextSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
device = NestedDeviceSerializer()
tenant = NestedTenantSerializer(required=False, allow_null=True, default=None)
primary_ip = NestedIPAddressSerializer(read_only=True)
primary_ip = NestedIPAddressSerializer(read_only=True, allow_null=True)
primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True)
primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True)
@@ -806,7 +815,8 @@ class PowerOutletSerializer(NetBoxModelSerializer, CabledObjectSerializer, Conne
type = ChoiceField(
choices=PowerOutletTypeChoices,
allow_blank=True,
required=False
required=False,
allow_null=True
)
power_port = NestedPowerPortSerializer(
required=False,
@@ -815,7 +825,8 @@ class PowerOutletSerializer(NetBoxModelSerializer, CabledObjectSerializer, Conne
feed_leg = ChoiceField(
choices=PowerOutletFeedLegChoices,
allow_blank=True,
required=False
required=False,
allow_null=True
)
class Meta:
@@ -838,7 +849,8 @@ class PowerPortSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
type = ChoiceField(
choices=PowerPortTypeChoices,
allow_blank=True,
required=False
required=False,
allow_null=True
)
class Meta:
@@ -868,12 +880,12 @@ class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
parent = NestedInterfaceSerializer(required=False, allow_null=True)
bridge = NestedInterfaceSerializer(required=False, allow_null=True)
lag = NestedInterfaceSerializer(required=False, allow_null=True)
mode = ChoiceField(choices=InterfaceModeChoices, required=False, allow_blank=True)
duplex = ChoiceField(choices=InterfaceDuplexChoices, required=False, allow_blank=True)
rf_role = ChoiceField(choices=WirelessRoleChoices, required=False, allow_blank=True)
rf_channel = ChoiceField(choices=WirelessChannelChoices, required=False, allow_blank=True)
poe_mode = ChoiceField(choices=InterfacePoEModeChoices, required=False, allow_blank=True)
poe_type = ChoiceField(choices=InterfacePoETypeChoices, required=False, allow_blank=True)
mode = ChoiceField(choices=InterfaceModeChoices, required=False, allow_blank=True, allow_null=True)
duplex = ChoiceField(choices=InterfaceDuplexChoices, required=False, allow_blank=True, allow_null=True)
rf_role = ChoiceField(choices=WirelessRoleChoices, required=False, allow_blank=True, allow_null=True)
rf_channel = ChoiceField(choices=WirelessChannelChoices, required=False, allow_blank=True, allow_null=True)
poe_mode = ChoiceField(choices=InterfacePoEModeChoices, required=False, allow_blank=True, allow_null=True)
poe_type = ChoiceField(choices=InterfacePoETypeChoices, required=False, allow_blank=True, allow_null=True)
untagged_vlan = NestedVLANSerializer(required=False, allow_null=True)
tagged_vlans = SerializedPKRelatedField(
queryset=VLAN.objects.all(),
@@ -882,8 +894,8 @@ class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
many=True
)
vrf = NestedVRFSerializer(required=False, allow_null=True)
l2vpn_termination = NestedL2VPNTerminationSerializer(read_only=True)
wireless_link = NestedWirelessLinkSerializer(read_only=True)
l2vpn_termination = NestedL2VPNTerminationSerializer(read_only=True, allow_null=True)
wireless_link = NestedWirelessLinkSerializer(read_only=True, allow_null=True)
wireless_lans = SerializedPKRelatedField(
queryset=WirelessLAN.objects.all(),
serializer=NestedWirelessLANSerializer,
@@ -892,6 +904,8 @@ class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
)
count_ipaddresses = serializers.IntegerField(read_only=True)
count_fhrp_groups = serializers.IntegerField(read_only=True)
mac_address = serializers.CharField(required=False, default=None)
wwn = serializers.CharField(required=False, default=None)
class Meta:
model = Interface
@@ -1015,7 +1029,7 @@ class InventoryItemSerializer(NetBoxModelSerializer):
'custom_fields', 'created', 'last_updated', '_depth',
]
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_component(self, obj):
if obj.component is None:
return None
@@ -1050,7 +1064,7 @@ class CableSerializer(NetBoxModelSerializer):
b_terminations = GenericObjectSerializer(many=True, required=False)
status = ChoiceField(choices=LinkStatusChoices, required=False)
tenant = NestedTenantSerializer(required=False, allow_null=True)
length_unit = ChoiceField(choices=CableLengthUnitChoices, allow_blank=True, required=False)
length_unit = ChoiceField(choices=CableLengthUnitChoices, allow_blank=True, required=False, allow_null=True)
class Meta:
model = Cable
@@ -1086,7 +1100,7 @@ class CableTerminationSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id', 'termination'
]
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_termination(self, obj):
serializer = get_serializer_for_model(obj.termination, prefix=NESTED_SERIALIZER_PREFIX)
context = {'request': self.context['request']}
@@ -1100,7 +1114,7 @@ class CablePathSerializer(serializers.ModelSerializer):
model = CablePath
fields = ['id', 'path', 'is_active', 'is_complete', 'is_split']
@swagger_serializer_method(serializer_or_field=serializers.ListField)
@extend_schema_field(serializers.ListField)
def get_path(self, obj):
ret = []
for nodes in obj.path_objects:
@@ -1159,19 +1173,19 @@ class PowerFeedSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
)
type = ChoiceField(
choices=PowerFeedTypeChoices,
default=PowerFeedTypeChoices.TYPE_PRIMARY
default=lambda: PowerFeedTypeChoices.TYPE_PRIMARY,
)
status = ChoiceField(
choices=PowerFeedStatusChoices,
default=PowerFeedStatusChoices.STATUS_ACTIVE
default=lambda: PowerFeedStatusChoices.STATUS_ACTIVE,
)
supply = ChoiceField(
choices=PowerFeedSupplyChoices,
default=PowerFeedSupplyChoices.SUPPLY_AC
default=lambda: PowerFeedSupplyChoices.SUPPLY_AC,
)
phase = ChoiceField(
choices=PowerFeedPhaseChoices,
default=PowerFeedPhaseChoices.PHASE_SINGLE
default=lambda: PowerFeedPhaseChoices.PHASE_SINGLE,
)
class Meta: