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

Refactor API serializers

This commit is contained in:
jeremystretch
2022-03-09 10:59:22 -05:00
parent 28f7b411ed
commit a11abf87ec
11 changed files with 275 additions and 256 deletions

View File

@ -5,7 +5,7 @@ from circuits.models import *
from dcim.api.nested_serializers import NestedCableSerializer, NestedSiteSerializer from dcim.api.nested_serializers import NestedCableSerializer, NestedSiteSerializer
from dcim.api.serializers import LinkTerminationSerializer from dcim.api.serializers import LinkTerminationSerializer
from netbox.api import ChoiceField from netbox.api import ChoiceField
from netbox.api.serializers import PrimaryModelSerializer, ValidatedModelSerializer, WritableNestedSerializer from netbox.api.serializers import NetBoxModelSerializer, ValidatedModelSerializer, WritableNestedSerializer
from tenancy.api.nested_serializers import NestedTenantSerializer from tenancy.api.nested_serializers import NestedTenantSerializer
from .nested_serializers import * from .nested_serializers import *
@ -14,7 +14,7 @@ from .nested_serializers import *
# Providers # Providers
# #
class ProviderSerializer(PrimaryModelSerializer): class ProviderSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provider-detail') url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provider-detail')
circuit_count = serializers.IntegerField(read_only=True) circuit_count = serializers.IntegerField(read_only=True)
@ -30,7 +30,7 @@ class ProviderSerializer(PrimaryModelSerializer):
# Provider networks # Provider networks
# #
class ProviderNetworkSerializer(PrimaryModelSerializer): class ProviderNetworkSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:providernetwork-detail') url = serializers.HyperlinkedIdentityField(view_name='circuits-api:providernetwork-detail')
provider = NestedProviderSerializer() provider = NestedProviderSerializer()
@ -46,7 +46,7 @@ class ProviderNetworkSerializer(PrimaryModelSerializer):
# Circuits # Circuits
# #
class CircuitTypeSerializer(PrimaryModelSerializer): class CircuitTypeSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittype-detail') url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittype-detail')
circuit_count = serializers.IntegerField(read_only=True) circuit_count = serializers.IntegerField(read_only=True)
@ -70,7 +70,7 @@ class CircuitCircuitTerminationSerializer(WritableNestedSerializer):
] ]
class CircuitSerializer(PrimaryModelSerializer): class CircuitSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail') url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail')
provider = NestedProviderSerializer() provider = NestedProviderSerializer()
status = ChoiceField(choices=CircuitStatusChoices, required=False) status = ChoiceField(choices=CircuitStatusChoices, required=False)

View File

@ -12,7 +12,7 @@ from ipam.api.nested_serializers import (
from ipam.models import ASN, VLAN from ipam.models import ASN, VLAN
from netbox.api import ChoiceField, ContentTypeField, SerializedPKRelatedField from netbox.api import ChoiceField, ContentTypeField, SerializedPKRelatedField
from netbox.api.serializers import ( from netbox.api.serializers import (
NestedGroupModelSerializer, PrimaryModelSerializer, ValidatedModelSerializer, WritableNestedSerializer, NestedGroupModelSerializer, NetBoxModelSerializer, ValidatedModelSerializer, WritableNestedSerializer,
) )
from netbox.config import ConfigItem from netbox.config import ConfigItem
from tenancy.api.nested_serializers import NestedTenantSerializer from tenancy.api.nested_serializers import NestedTenantSerializer
@ -109,7 +109,7 @@ class SiteGroupSerializer(NestedGroupModelSerializer):
] ]
class SiteSerializer(PrimaryModelSerializer): class SiteSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail')
status = ChoiceField(choices=SiteStatusChoices, required=False) status = ChoiceField(choices=SiteStatusChoices, required=False)
region = NestedRegionSerializer(required=False, allow_null=True) region = NestedRegionSerializer(required=False, allow_null=True)
@ -161,7 +161,7 @@ class LocationSerializer(NestedGroupModelSerializer):
] ]
class RackRoleSerializer(PrimaryModelSerializer): class RackRoleSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail')
rack_count = serializers.IntegerField(read_only=True) rack_count = serializers.IntegerField(read_only=True)
@ -173,7 +173,7 @@ class RackRoleSerializer(PrimaryModelSerializer):
] ]
class RackSerializer(PrimaryModelSerializer): class RackSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail')
site = NestedSiteSerializer() site = NestedSiteSerializer()
location = NestedLocationSerializer(required=False, allow_null=True, default=None) location = NestedLocationSerializer(required=False, allow_null=True, default=None)
@ -212,7 +212,7 @@ class RackUnitSerializer(serializers.Serializer):
return obj['name'] return obj['name']
class RackReservationSerializer(PrimaryModelSerializer): class RackReservationSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackreservation-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackreservation-detail')
rack = NestedRackSerializer() rack = NestedRackSerializer()
user = NestedUserSerializer() user = NestedUserSerializer()
@ -266,7 +266,7 @@ class RackElevationDetailFilterSerializer(serializers.Serializer):
# Device/module types # Device/module types
# #
class ManufacturerSerializer(PrimaryModelSerializer): class ManufacturerSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail')
devicetype_count = serializers.IntegerField(read_only=True) devicetype_count = serializers.IntegerField(read_only=True)
inventoryitem_count = serializers.IntegerField(read_only=True) inventoryitem_count = serializers.IntegerField(read_only=True)
@ -280,7 +280,7 @@ class ManufacturerSerializer(PrimaryModelSerializer):
] ]
class DeviceTypeSerializer(PrimaryModelSerializer): class DeviceTypeSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail')
manufacturer = NestedManufacturerSerializer() manufacturer = NestedManufacturerSerializer()
subdevice_role = ChoiceField(choices=SubdeviceRoleChoices, allow_blank=True, required=False) subdevice_role = ChoiceField(choices=SubdeviceRoleChoices, allow_blank=True, required=False)
@ -296,7 +296,7 @@ class DeviceTypeSerializer(PrimaryModelSerializer):
] ]
class ModuleTypeSerializer(PrimaryModelSerializer): class ModuleTypeSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:moduletype-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:moduletype-detail')
manufacturer = NestedManufacturerSerializer() manufacturer = NestedManufacturerSerializer()
# module_count = serializers.IntegerField(read_only=True) # module_count = serializers.IntegerField(read_only=True)
@ -487,7 +487,7 @@ class InventoryItemTemplateSerializer(ValidatedModelSerializer):
# Devices # Devices
# #
class DeviceRoleSerializer(PrimaryModelSerializer): class DeviceRoleSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
device_count = serializers.IntegerField(read_only=True) device_count = serializers.IntegerField(read_only=True)
virtualmachine_count = serializers.IntegerField(read_only=True) virtualmachine_count = serializers.IntegerField(read_only=True)
@ -500,7 +500,7 @@ class DeviceRoleSerializer(PrimaryModelSerializer):
] ]
class PlatformSerializer(PrimaryModelSerializer): class PlatformSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail')
manufacturer = NestedManufacturerSerializer(required=False, allow_null=True) manufacturer = NestedManufacturerSerializer(required=False, allow_null=True)
device_count = serializers.IntegerField(read_only=True) device_count = serializers.IntegerField(read_only=True)
@ -514,7 +514,7 @@ class PlatformSerializer(PrimaryModelSerializer):
] ]
class DeviceSerializer(PrimaryModelSerializer): class DeviceSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
device_role = NestedDeviceRoleSerializer() device_role = NestedDeviceRoleSerializer()
@ -556,7 +556,7 @@ class DeviceSerializer(PrimaryModelSerializer):
return data return data
class ModuleSerializer(PrimaryModelSerializer): class ModuleSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:module-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:module-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
module_bay = NestedModuleBaySerializer() module_bay = NestedModuleBaySerializer()
@ -594,7 +594,7 @@ class DeviceNAPALMSerializer(serializers.Serializer):
# Device components # Device components
# #
class ConsoleServerPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer): class ConsoleServerPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
module = ComponentNestedModuleSerializer( module = ComponentNestedModuleSerializer(
@ -622,7 +622,7 @@ class ConsoleServerPortSerializer(PrimaryModelSerializer, LinkTerminationSeriali
] ]
class ConsolePortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer): class ConsolePortSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
module = ComponentNestedModuleSerializer( module = ComponentNestedModuleSerializer(
@ -650,7 +650,7 @@ class ConsolePortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, C
] ]
class PowerOutletSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer): class PowerOutletSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
module = ComponentNestedModuleSerializer( module = ComponentNestedModuleSerializer(
@ -685,7 +685,7 @@ class PowerOutletSerializer(PrimaryModelSerializer, LinkTerminationSerializer, C
] ]
class PowerPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer): class PowerPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
module = ComponentNestedModuleSerializer( module = ComponentNestedModuleSerializer(
@ -709,7 +709,7 @@ class PowerPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, Con
] ]
class InterfaceSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer): class InterfaceSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
module = ComponentNestedModuleSerializer( module = ComponentNestedModuleSerializer(
@ -768,7 +768,7 @@ class InterfaceSerializer(PrimaryModelSerializer, LinkTerminationSerializer, Con
return super().validate(data) return super().validate(data)
class RearPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer): class RearPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
module = ComponentNestedModuleSerializer( module = ComponentNestedModuleSerializer(
@ -798,7 +798,7 @@ class FrontPortRearPortSerializer(WritableNestedSerializer):
fields = ['id', 'url', 'display', 'name', 'label'] fields = ['id', 'url', 'display', 'name', 'label']
class FrontPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer): class FrontPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
module = ComponentNestedModuleSerializer( module = ComponentNestedModuleSerializer(
@ -818,7 +818,7 @@ class FrontPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer):
] ]
class ModuleBaySerializer(PrimaryModelSerializer): class ModuleBaySerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:modulebay-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:modulebay-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
# installed_module = NestedModuleSerializer(required=False, allow_null=True) # installed_module = NestedModuleSerializer(required=False, allow_null=True)
@ -831,7 +831,7 @@ class ModuleBaySerializer(PrimaryModelSerializer):
] ]
class DeviceBaySerializer(PrimaryModelSerializer): class DeviceBaySerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebay-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebay-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
installed_device = NestedDeviceSerializer(required=False, allow_null=True) installed_device = NestedDeviceSerializer(required=False, allow_null=True)
@ -844,7 +844,7 @@ class DeviceBaySerializer(PrimaryModelSerializer):
] ]
class InventoryItemSerializer(PrimaryModelSerializer): class InventoryItemSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:inventoryitem-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:inventoryitem-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
parent = serializers.PrimaryKeyRelatedField(queryset=InventoryItem.objects.all(), allow_null=True, default=None) parent = serializers.PrimaryKeyRelatedField(queryset=InventoryItem.objects.all(), allow_null=True, default=None)
@ -879,7 +879,7 @@ class InventoryItemSerializer(PrimaryModelSerializer):
# Device component roles # Device component roles
# #
class InventoryItemRoleSerializer(PrimaryModelSerializer): class InventoryItemRoleSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:inventoryitemrole-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:inventoryitemrole-detail')
inventoryitem_count = serializers.IntegerField(read_only=True) inventoryitem_count = serializers.IntegerField(read_only=True)
@ -895,7 +895,7 @@ class InventoryItemRoleSerializer(PrimaryModelSerializer):
# Cables # Cables
# #
class CableSerializer(PrimaryModelSerializer): class CableSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail')
termination_a_type = ContentTypeField( termination_a_type = ContentTypeField(
queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS) queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)
@ -1001,7 +1001,7 @@ class CablePathSerializer(serializers.ModelSerializer):
# Virtual chassis # Virtual chassis
# #
class VirtualChassisSerializer(PrimaryModelSerializer): class VirtualChassisSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualchassis-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualchassis-detail')
master = NestedDeviceSerializer(required=False) master = NestedDeviceSerializer(required=False)
member_count = serializers.IntegerField(read_only=True) member_count = serializers.IntegerField(read_only=True)
@ -1018,7 +1018,7 @@ class VirtualChassisSerializer(PrimaryModelSerializer):
# Power panels # Power panels
# #
class PowerPanelSerializer(PrimaryModelSerializer): class PowerPanelSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerpanel-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerpanel-detail')
site = NestedSiteSerializer() site = NestedSiteSerializer()
location = NestedLocationSerializer( location = NestedLocationSerializer(
@ -1036,7 +1036,7 @@ class PowerPanelSerializer(PrimaryModelSerializer):
] ]
class PowerFeedSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer): class PowerFeedSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerfeed-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerfeed-detail')
power_panel = NestedPowerPanelSerializer() power_panel = NestedPowerPanelSerializer()
rack = NestedRackSerializer( rack = NestedRackSerializer(

View File

@ -9,7 +9,7 @@ from ipam.choices import *
from ipam.constants import IPADDRESS_ASSIGNMENT_MODELS, VLANGROUP_SCOPE_TYPES from ipam.constants import IPADDRESS_ASSIGNMENT_MODELS, VLANGROUP_SCOPE_TYPES
from ipam.models import * from ipam.models import *
from netbox.api import ChoiceField, ContentTypeField, SerializedPKRelatedField from netbox.api import ChoiceField, ContentTypeField, SerializedPKRelatedField
from netbox.api.serializers import PrimaryModelSerializer from netbox.api.serializers import NetBoxModelSerializer
from tenancy.api.nested_serializers import NestedTenantSerializer from tenancy.api.nested_serializers import NestedTenantSerializer
from utilities.api import get_serializer_for_model from utilities.api import get_serializer_for_model
from virtualization.api.nested_serializers import NestedVirtualMachineSerializer from virtualization.api.nested_serializers import NestedVirtualMachineSerializer
@ -20,7 +20,7 @@ from .nested_serializers import *
# ASNs # ASNs
# #
class ASNSerializer(PrimaryModelSerializer): class ASNSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:asn-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:asn-detail')
tenant = NestedTenantSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True)
site_count = serializers.IntegerField(read_only=True) site_count = serializers.IntegerField(read_only=True)
@ -37,7 +37,7 @@ class ASNSerializer(PrimaryModelSerializer):
# VRFs # VRFs
# #
class VRFSerializer(PrimaryModelSerializer): class VRFSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail')
tenant = NestedTenantSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True)
import_targets = SerializedPKRelatedField( import_targets = SerializedPKRelatedField(
@ -67,7 +67,7 @@ class VRFSerializer(PrimaryModelSerializer):
# Route targets # Route targets
# #
class RouteTargetSerializer(PrimaryModelSerializer): class RouteTargetSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:routetarget-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:routetarget-detail')
tenant = NestedTenantSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True)
@ -82,7 +82,7 @@ class RouteTargetSerializer(PrimaryModelSerializer):
# RIRs/aggregates # RIRs/aggregates
# #
class RIRSerializer(PrimaryModelSerializer): class RIRSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:rir-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:rir-detail')
aggregate_count = serializers.IntegerField(read_only=True) aggregate_count = serializers.IntegerField(read_only=True)
@ -94,7 +94,7 @@ class RIRSerializer(PrimaryModelSerializer):
] ]
class AggregateSerializer(PrimaryModelSerializer): class AggregateSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:aggregate-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:aggregate-detail')
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True) family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
rir = NestedRIRSerializer() rir = NestedRIRSerializer()
@ -113,7 +113,7 @@ class AggregateSerializer(PrimaryModelSerializer):
# FHRP Groups # FHRP Groups
# #
class FHRPGroupSerializer(PrimaryModelSerializer): class FHRPGroupSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:fhrpgroup-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:fhrpgroup-detail')
ip_addresses = NestedIPAddressSerializer(many=True, read_only=True) ip_addresses = NestedIPAddressSerializer(many=True, read_only=True)
@ -125,7 +125,7 @@ class FHRPGroupSerializer(PrimaryModelSerializer):
] ]
class FHRPGroupAssignmentSerializer(PrimaryModelSerializer): class FHRPGroupAssignmentSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:fhrpgroupassignment-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:fhrpgroupassignment-detail')
group = NestedFHRPGroupSerializer() group = NestedFHRPGroupSerializer()
interface_type = ContentTypeField( interface_type = ContentTypeField(
@ -153,7 +153,7 @@ class FHRPGroupAssignmentSerializer(PrimaryModelSerializer):
# VLANs # VLANs
# #
class RoleSerializer(PrimaryModelSerializer): class RoleSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:role-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:role-detail')
prefix_count = serializers.IntegerField(read_only=True) prefix_count = serializers.IntegerField(read_only=True)
vlan_count = serializers.IntegerField(read_only=True) vlan_count = serializers.IntegerField(read_only=True)
@ -166,7 +166,7 @@ class RoleSerializer(PrimaryModelSerializer):
] ]
class VLANGroupSerializer(PrimaryModelSerializer): class VLANGroupSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlangroup-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlangroup-detail')
scope_type = ContentTypeField( scope_type = ContentTypeField(
queryset=ContentType.objects.filter( queryset=ContentType.objects.filter(
@ -196,7 +196,7 @@ class VLANGroupSerializer(PrimaryModelSerializer):
return serializer(obj.scope, context=context).data return serializer(obj.scope, context=context).data
class VLANSerializer(PrimaryModelSerializer): class VLANSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
site = NestedSiteSerializer(required=False, allow_null=True) site = NestedSiteSerializer(required=False, allow_null=True)
group = NestedVLANGroupSerializer(required=False, allow_null=True, default=None) group = NestedVLANGroupSerializer(required=False, allow_null=True, default=None)
@ -230,7 +230,7 @@ class AvailableVLANSerializer(serializers.Serializer):
]) ])
class CreateAvailableVLANSerializer(PrimaryModelSerializer): class CreateAvailableVLANSerializer(NetBoxModelSerializer):
site = NestedSiteSerializer(required=False, allow_null=True) site = NestedSiteSerializer(required=False, allow_null=True)
tenant = NestedTenantSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True)
status = ChoiceField(choices=VLANStatusChoices, required=False) status = ChoiceField(choices=VLANStatusChoices, required=False)
@ -251,7 +251,7 @@ class CreateAvailableVLANSerializer(PrimaryModelSerializer):
# Prefixes # Prefixes
# #
class PrefixSerializer(PrimaryModelSerializer): class PrefixSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:prefix-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:prefix-detail')
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True) family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
site = NestedSiteSerializer(required=False, allow_null=True) site = NestedSiteSerializer(required=False, allow_null=True)
@ -323,7 +323,7 @@ class AvailablePrefixSerializer(serializers.Serializer):
# IP ranges # IP ranges
# #
class IPRangeSerializer(PrimaryModelSerializer): class IPRangeSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:iprange-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:iprange-detail')
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True) family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
vrf = NestedVRFSerializer(required=False, allow_null=True) vrf = NestedVRFSerializer(required=False, allow_null=True)
@ -345,7 +345,7 @@ class IPRangeSerializer(PrimaryModelSerializer):
# IP addresses # IP addresses
# #
class IPAddressSerializer(PrimaryModelSerializer): class IPAddressSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True) family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
vrf = NestedVRFSerializer(required=False, allow_null=True) vrf = NestedVRFSerializer(required=False, allow_null=True)
@ -403,7 +403,7 @@ class AvailableIPSerializer(serializers.Serializer):
# Services # Services
# #
class ServiceTemplateSerializer(PrimaryModelSerializer): class ServiceTemplateSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:servicetemplate-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:servicetemplate-detail')
protocol = ChoiceField(choices=ServiceProtocolChoices, required=False) protocol = ChoiceField(choices=ServiceProtocolChoices, required=False)
@ -415,7 +415,7 @@ class ServiceTemplateSerializer(PrimaryModelSerializer):
] ]
class ServiceSerializer(PrimaryModelSerializer): class ServiceSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:service-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:service-detail')
device = NestedDeviceSerializer(required=False, allow_null=True) device = NestedDeviceSerializer(required=False, allow_null=True)
virtual_machine = NestedVirtualMachineSerializer(required=False, allow_null=True) virtual_machine = NestedVirtualMachineSerializer(required=False, allow_null=True)

View File

@ -1,193 +0,0 @@
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import FieldError, MultipleObjectsReturned, ObjectDoesNotExist
from django.db.models import ManyToManyField
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework.fields import CreateOnlyDefault
from extras.api.customfields import CustomFieldsDataField, CustomFieldDefaultValues
from extras.models import CustomField, Tag
from utilities.utils import dict_to_filter_params
class BaseModelSerializer(serializers.ModelSerializer):
display = serializers.SerializerMethodField(read_only=True)
def get_display(self, obj):
return str(obj)
class ValidatedModelSerializer(BaseModelSerializer):
"""
Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during
validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
"""
def validate(self, data):
# Remove custom fields data and tags (if any) prior to model validation
attrs = data.copy()
attrs.pop('custom_fields', None)
attrs.pop('tags', None)
# Skip ManyToManyFields
for field in self.Meta.model._meta.get_fields():
if isinstance(field, ManyToManyField):
attrs.pop(field.name, None)
# Run clean() on an instance of the model
if self.instance is None:
instance = self.Meta.model(**attrs)
else:
instance = self.instance
for k, v in attrs.items():
setattr(instance, k, v)
instance.full_clean()
return data
class CustomFieldModelSerializer(ValidatedModelSerializer):
"""
Extends ModelSerializer to render any CustomFields and their values associated with an object.
"""
custom_fields = CustomFieldsDataField(
source='custom_field_data',
default=CreateOnlyDefault(CustomFieldDefaultValues())
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance is not None:
# Retrieve the set of CustomFields which apply to this type of object
content_type = ContentType.objects.get_for_model(self.Meta.model)
fields = CustomField.objects.filter(content_types=content_type)
# Populate CustomFieldValues for each instance from database
if type(self.instance) in (list, tuple):
for obj in self.instance:
self._populate_custom_fields(obj, fields)
else:
self._populate_custom_fields(self.instance, fields)
def _populate_custom_fields(self, instance, custom_fields):
instance.custom_fields = {}
for field in custom_fields:
instance.custom_fields[field.name] = instance.cf.get(field.name)
#
# Nested serializers
#
class WritableNestedSerializer(BaseModelSerializer):
"""
Returns a nested representation of an object on read, but accepts only a primary key on write.
"""
def to_internal_value(self, data):
if data is None:
return None
# Dictionary of related object attributes
if isinstance(data, dict):
params = dict_to_filter_params(data)
queryset = self.Meta.model.objects
try:
return queryset.get(**params)
except ObjectDoesNotExist:
raise ValidationError(
"Related object not found using the provided attributes: {}".format(params)
)
except MultipleObjectsReturned:
raise ValidationError(
"Multiple objects match the provided attributes: {}".format(params)
)
except FieldError as e:
raise ValidationError(e)
# Integer PK of related object
if isinstance(data, int):
pk = data
else:
try:
# PK might have been mistakenly passed as a string
pk = int(data)
except (TypeError, ValueError):
raise ValidationError(
"Related objects must be referenced by numeric ID or by dictionary of attributes. Received an "
"unrecognized value: {}".format(data)
)
# Look up object by PK
queryset = self.Meta.model.objects
try:
return queryset.get(pk=int(data))
except ObjectDoesNotExist:
raise ValidationError(
"Related object not found using the provided numeric ID: {}".format(pk)
)
#
# Nested tags serialization
#
# Declared here for use by PrimaryModelSerializer, but should be imported from extras.api.nested_serializers
class NestedTagSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='extras-api:tag-detail')
class Meta:
model = Tag
fields = ['id', 'url', 'display', 'name', 'slug', 'color']
#
# Base model serializers
#
class PrimaryModelSerializer(CustomFieldModelSerializer):
"""
Adds support for custom fields and tags.
"""
tags = NestedTagSerializer(many=True, required=False)
def create(self, validated_data):
tags = validated_data.pop('tags', None)
instance = super().create(validated_data)
if tags is not None:
return self._save_tags(instance, tags)
return instance
def update(self, instance, validated_data):
tags = validated_data.pop('tags', None)
# Cache tags on instance for change logging
instance._tags = tags or []
instance = super().update(instance, validated_data)
if tags is not None:
return self._save_tags(instance, tags)
return instance
def _save_tags(self, instance, tags):
if tags:
instance.tags.set([t.name for t in tags])
else:
instance.tags.clear()
return instance
class NestedGroupModelSerializer(PrimaryModelSerializer):
"""
Extends PrimaryModelSerializer to include MPTT support.
"""
_depth = serializers.IntegerField(source='level', read_only=True)
class BulkOperationSerializer(serializers.Serializer):
id = serializers.IntegerField()

View File

@ -0,0 +1,27 @@
from rest_framework import serializers
from .base import *
from .features import *
from .nested import *
#
# Base model serializers
#
class NetBoxModelSerializer(TaggableObjectSerializer, CustomFieldModelSerializer, ValidatedModelSerializer):
"""
Adds support for custom fields and tags.
"""
pass
class NestedGroupModelSerializer(NetBoxModelSerializer):
"""
Extends PrimaryModelSerializer to include MPTT support.
"""
_depth = serializers.IntegerField(source='level', read_only=True)
class BulkOperationSerializer(serializers.Serializer):
id = serializers.IntegerField()

View File

@ -0,0 +1,43 @@
from django.db.models import ManyToManyField
from rest_framework import serializers
__all__ = (
'BaseModelSerializer',
'ValidatedModelSerializer',
)
class BaseModelSerializer(serializers.ModelSerializer):
display = serializers.SerializerMethodField(read_only=True)
def get_display(self, obj):
return str(obj)
class ValidatedModelSerializer(BaseModelSerializer):
"""
Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during
validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
"""
def validate(self, data):
# Remove custom fields data and tags (if any) prior to model validation
attrs = data.copy()
attrs.pop('custom_fields', None)
attrs.pop('tags', None)
# Skip ManyToManyFields
for field in self.Meta.model._meta.get_fields():
if isinstance(field, ManyToManyField):
attrs.pop(field.name, None)
# Run clean() on an instance of the model
if self.instance is None:
instance = self.Meta.model(**attrs)
else:
instance = self.instance
for k, v in attrs.items():
setattr(instance, k, v)
instance.full_clean()
return data

View File

@ -0,0 +1,80 @@
from django.contrib.contenttypes.models import ContentType
from rest_framework import serializers
from rest_framework.fields import CreateOnlyDefault
from extras.api.customfields import CustomFieldsDataField, CustomFieldDefaultValues
from extras.models import CustomField
from .nested import NestedTagSerializer
__all__ = (
'CustomFieldModelSerializer',
'TaggableObjectSerializer',
)
class CustomFieldModelSerializer(serializers.Serializer):
"""
Introduces support for custom field assignment. Adds `custom_fields` serialization and ensures
that custom field data is populated upon initialization.
"""
custom_fields = CustomFieldsDataField(
source='custom_field_data',
default=CreateOnlyDefault(CustomFieldDefaultValues())
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance is not None:
# Retrieve the set of CustomFields which apply to this type of object
content_type = ContentType.objects.get_for_model(self.Meta.model)
fields = CustomField.objects.filter(content_types=content_type)
# Populate custom field values for each instance from database
if type(self.instance) in (list, tuple):
for obj in self.instance:
self._populate_custom_fields(obj, fields)
else:
self._populate_custom_fields(self.instance, fields)
def _populate_custom_fields(self, instance, custom_fields):
instance.custom_fields = {}
for field in custom_fields:
instance.custom_fields[field.name] = instance.cf.get(field.name)
class TaggableObjectSerializer(serializers.Serializer):
"""
Introduces support for Tag assignment. Adds `tags` serialization, and handles tag assignment
on create() and update().
"""
tags = NestedTagSerializer(many=True, required=False)
def create(self, validated_data):
tags = validated_data.pop('tags', None)
instance = super().create(validated_data)
if tags is not None:
return self._save_tags(instance, tags)
return instance
def update(self, instance, validated_data):
tags = validated_data.pop('tags', None)
# Cache tags on instance for change logging
instance._tags = tags or []
instance = super().update(instance, validated_data)
if tags is not None:
return self._save_tags(instance, tags)
return instance
def _save_tags(self, instance, tags):
if tags:
instance.tags.set([t.name for t in tags])
else:
instance.tags.clear()
return instance

View File

@ -0,0 +1,62 @@
from django.core.exceptions import FieldError, MultipleObjectsReturned, ObjectDoesNotExist
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from extras.models import Tag
from utilities.utils import dict_to_filter_params
from .base import BaseModelSerializer
__all__ = (
'NestedTagSerializer',
'WritableNestedSerializer',
)
class WritableNestedSerializer(BaseModelSerializer):
"""
Represents an object related through a ForeignKey field. On write, it accepts a primary key (PK) value or a
dictionary of attributes which can be used to uniquely identify the related object. This class should be
subclassed to return a full representation of the related object on read.
"""
def to_internal_value(self, data):
if data is None:
return None
# Dictionary of related object attributes
if isinstance(data, dict):
params = dict_to_filter_params(data)
queryset = self.Meta.model.objects
try:
return queryset.get(**params)
except ObjectDoesNotExist:
raise ValidationError(f"Related object not found using the provided attributes: {params}")
except MultipleObjectsReturned:
raise ValidationError(f"Multiple objects match the provided attributes: {params}")
except FieldError as e:
raise ValidationError(e)
# Integer PK of related object
try:
# Cast as integer in case a PK was mistakenly sent as a string
pk = int(data)
except (TypeError, ValueError):
raise ValidationError(
f"Related objects must be referenced by numeric ID or by dictionary of attributes. Received an "
f"unrecognized value: {data}"
)
# Look up object by PK
try:
return self.Meta.model.objects.get(pk=pk)
except ObjectDoesNotExist:
raise ValidationError(f"Related object not found using the provided numeric ID: {pk}")
# Declared here for use by PrimaryModelSerializer, but should be imported from extras.api.nested_serializers
class NestedTagSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='extras-api:tag-detail')
class Meta:
model = Tag
fields = ['id', 'url', 'display', 'name', 'slug', 'color']

View File

@ -3,7 +3,7 @@ from drf_yasg.utils import swagger_serializer_method
from rest_framework import serializers from rest_framework import serializers
from netbox.api import ChoiceField, ContentTypeField from netbox.api import ChoiceField, ContentTypeField
from netbox.api.serializers import NestedGroupModelSerializer, PrimaryModelSerializer from netbox.api.serializers import NestedGroupModelSerializer, NetBoxModelSerializer
from tenancy.choices import ContactPriorityChoices from tenancy.choices import ContactPriorityChoices
from tenancy.models import * from tenancy.models import *
from utilities.api import get_serializer_for_model from utilities.api import get_serializer_for_model
@ -27,7 +27,7 @@ class TenantGroupSerializer(NestedGroupModelSerializer):
] ]
class TenantSerializer(PrimaryModelSerializer): class TenantSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenant-detail') url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenant-detail')
group = NestedTenantGroupSerializer(required=False, allow_null=True) group = NestedTenantGroupSerializer(required=False, allow_null=True)
circuit_count = serializers.IntegerField(read_only=True) circuit_count = serializers.IntegerField(read_only=True)
@ -67,7 +67,7 @@ class ContactGroupSerializer(NestedGroupModelSerializer):
] ]
class ContactRoleSerializer(PrimaryModelSerializer): class ContactRoleSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:contactrole-detail') url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:contactrole-detail')
class Meta: class Meta:
@ -77,7 +77,7 @@ class ContactRoleSerializer(PrimaryModelSerializer):
] ]
class ContactSerializer(PrimaryModelSerializer): class ContactSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:contact-detail') url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:contact-detail')
group = NestedContactGroupSerializer(required=False, allow_null=True, default=None) group = NestedContactGroupSerializer(required=False, allow_null=True, default=None)
@ -89,7 +89,7 @@ class ContactSerializer(PrimaryModelSerializer):
] ]
class ContactAssignmentSerializer(PrimaryModelSerializer): class ContactAssignmentSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:contactassignment-detail') url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:contactassignment-detail')
content_type = ContentTypeField( content_type = ContentTypeField(
queryset=ContentType.objects.all() queryset=ContentType.objects.all()

View File

@ -6,7 +6,7 @@ from dcim.choices import InterfaceModeChoices
from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer, NestedVRFSerializer from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer, NestedVRFSerializer
from ipam.models import VLAN from ipam.models import VLAN
from netbox.api import ChoiceField, SerializedPKRelatedField from netbox.api import ChoiceField, SerializedPKRelatedField
from netbox.api.serializers import PrimaryModelSerializer from netbox.api.serializers import NetBoxModelSerializer
from tenancy.api.nested_serializers import NestedTenantSerializer from tenancy.api.nested_serializers import NestedTenantSerializer
from virtualization.choices import * from virtualization.choices import *
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
@ -17,7 +17,7 @@ from .nested_serializers import *
# Clusters # Clusters
# #
class ClusterTypeSerializer(PrimaryModelSerializer): class ClusterTypeSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustertype-detail') url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustertype-detail')
cluster_count = serializers.IntegerField(read_only=True) cluster_count = serializers.IntegerField(read_only=True)
@ -29,7 +29,7 @@ class ClusterTypeSerializer(PrimaryModelSerializer):
] ]
class ClusterGroupSerializer(PrimaryModelSerializer): class ClusterGroupSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustergroup-detail') url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustergroup-detail')
cluster_count = serializers.IntegerField(read_only=True) cluster_count = serializers.IntegerField(read_only=True)
@ -41,7 +41,7 @@ class ClusterGroupSerializer(PrimaryModelSerializer):
] ]
class ClusterSerializer(PrimaryModelSerializer): class ClusterSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:cluster-detail') url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:cluster-detail')
type = NestedClusterTypeSerializer() type = NestedClusterTypeSerializer()
group = NestedClusterGroupSerializer(required=False, allow_null=True, default=None) group = NestedClusterGroupSerializer(required=False, allow_null=True, default=None)
@ -62,7 +62,7 @@ class ClusterSerializer(PrimaryModelSerializer):
# Virtual machines # Virtual machines
# #
class VirtualMachineSerializer(PrimaryModelSerializer): class VirtualMachineSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:virtualmachine-detail') url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:virtualmachine-detail')
status = ChoiceField(choices=VirtualMachineStatusChoices, required=False) status = ChoiceField(choices=VirtualMachineStatusChoices, required=False)
site = NestedSiteSerializer(read_only=True) site = NestedSiteSerializer(read_only=True)
@ -103,7 +103,7 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer):
# VM interfaces # VM interfaces
# #
class VMInterfaceSerializer(PrimaryModelSerializer): class VMInterfaceSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:vminterface-detail') url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:vminterface-detail')
virtual_machine = NestedVirtualMachineSerializer() virtual_machine = NestedVirtualMachineSerializer()
parent = NestedVMInterfaceSerializer(required=False, allow_null=True) parent = NestedVMInterfaceSerializer(required=False, allow_null=True)

View File

@ -4,7 +4,7 @@ from dcim.choices import LinkStatusChoices
from dcim.api.serializers import NestedInterfaceSerializer from dcim.api.serializers import NestedInterfaceSerializer
from ipam.api.serializers import NestedVLANSerializer from ipam.api.serializers import NestedVLANSerializer
from netbox.api import ChoiceField from netbox.api import ChoiceField
from netbox.api.serializers import NestedGroupModelSerializer, PrimaryModelSerializer from netbox.api.serializers import NestedGroupModelSerializer, NetBoxModelSerializer
from wireless.choices import * from wireless.choices import *
from wireless.models import * from wireless.models import *
from .nested_serializers import * from .nested_serializers import *
@ -29,7 +29,7 @@ class WirelessLANGroupSerializer(NestedGroupModelSerializer):
] ]
class WirelessLANSerializer(PrimaryModelSerializer): class WirelessLANSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='wireless-api:wirelesslan-detail') url = serializers.HyperlinkedIdentityField(view_name='wireless-api:wirelesslan-detail')
group = NestedWirelessLANGroupSerializer(required=False, allow_null=True) group = NestedWirelessLANGroupSerializer(required=False, allow_null=True)
vlan = NestedVLANSerializer(required=False, allow_null=True) vlan = NestedVLANSerializer(required=False, allow_null=True)
@ -44,7 +44,7 @@ class WirelessLANSerializer(PrimaryModelSerializer):
] ]
class WirelessLinkSerializer(PrimaryModelSerializer): class WirelessLinkSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='wireless-api:wirelesslink-detail') url = serializers.HyperlinkedIdentityField(view_name='wireless-api:wirelesslink-detail')
status = ChoiceField(choices=LinkStatusChoices, required=False) status = ChoiceField(choices=LinkStatusChoices, required=False)
interface_a = NestedInterfaceSerializer() interface_a = NestedInterfaceSerializer()