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:
@ -5,7 +5,7 @@ from circuits.models import *
|
||||
from dcim.api.nested_serializers import NestedCableSerializer, NestedSiteSerializer
|
||||
from dcim.api.serializers import LinkTerminationSerializer
|
||||
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 .nested_serializers import *
|
||||
|
||||
@ -14,7 +14,7 @@ from .nested_serializers import *
|
||||
# Providers
|
||||
#
|
||||
|
||||
class ProviderSerializer(PrimaryModelSerializer):
|
||||
class ProviderSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provider-detail')
|
||||
circuit_count = serializers.IntegerField(read_only=True)
|
||||
|
||||
@ -30,7 +30,7 @@ class ProviderSerializer(PrimaryModelSerializer):
|
||||
# Provider networks
|
||||
#
|
||||
|
||||
class ProviderNetworkSerializer(PrimaryModelSerializer):
|
||||
class ProviderNetworkSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:providernetwork-detail')
|
||||
provider = NestedProviderSerializer()
|
||||
|
||||
@ -46,7 +46,7 @@ class ProviderNetworkSerializer(PrimaryModelSerializer):
|
||||
# Circuits
|
||||
#
|
||||
|
||||
class CircuitTypeSerializer(PrimaryModelSerializer):
|
||||
class CircuitTypeSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittype-detail')
|
||||
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')
|
||||
provider = NestedProviderSerializer()
|
||||
status = ChoiceField(choices=CircuitStatusChoices, required=False)
|
||||
|
@ -12,7 +12,7 @@ from ipam.api.nested_serializers import (
|
||||
from ipam.models import ASN, VLAN
|
||||
from netbox.api import ChoiceField, ContentTypeField, SerializedPKRelatedField
|
||||
from netbox.api.serializers import (
|
||||
NestedGroupModelSerializer, PrimaryModelSerializer, ValidatedModelSerializer, WritableNestedSerializer,
|
||||
NestedGroupModelSerializer, NetBoxModelSerializer, ValidatedModelSerializer, WritableNestedSerializer,
|
||||
)
|
||||
from netbox.config import ConfigItem
|
||||
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')
|
||||
status = ChoiceField(choices=SiteStatusChoices, required=False)
|
||||
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')
|
||||
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')
|
||||
site = NestedSiteSerializer()
|
||||
location = NestedLocationSerializer(required=False, allow_null=True, default=None)
|
||||
@ -212,7 +212,7 @@ class RackUnitSerializer(serializers.Serializer):
|
||||
return obj['name']
|
||||
|
||||
|
||||
class RackReservationSerializer(PrimaryModelSerializer):
|
||||
class RackReservationSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackreservation-detail')
|
||||
rack = NestedRackSerializer()
|
||||
user = NestedUserSerializer()
|
||||
@ -266,7 +266,7 @@ class RackElevationDetailFilterSerializer(serializers.Serializer):
|
||||
# Device/module types
|
||||
#
|
||||
|
||||
class ManufacturerSerializer(PrimaryModelSerializer):
|
||||
class ManufacturerSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail')
|
||||
devicetype_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')
|
||||
manufacturer = NestedManufacturerSerializer()
|
||||
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')
|
||||
manufacturer = NestedManufacturerSerializer()
|
||||
# module_count = serializers.IntegerField(read_only=True)
|
||||
@ -487,7 +487,7 @@ class InventoryItemTemplateSerializer(ValidatedModelSerializer):
|
||||
# Devices
|
||||
#
|
||||
|
||||
class DeviceRoleSerializer(PrimaryModelSerializer):
|
||||
class DeviceRoleSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
|
||||
device_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')
|
||||
manufacturer = NestedManufacturerSerializer(required=False, allow_null=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')
|
||||
device_type = NestedDeviceTypeSerializer()
|
||||
device_role = NestedDeviceRoleSerializer()
|
||||
@ -556,7 +556,7 @@ class DeviceSerializer(PrimaryModelSerializer):
|
||||
return data
|
||||
|
||||
|
||||
class ModuleSerializer(PrimaryModelSerializer):
|
||||
class ModuleSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:module-detail')
|
||||
device = NestedDeviceSerializer()
|
||||
module_bay = NestedModuleBaySerializer()
|
||||
@ -594,7 +594,7 @@ class DeviceNAPALMSerializer(serializers.Serializer):
|
||||
# Device components
|
||||
#
|
||||
|
||||
class ConsoleServerPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
|
||||
class ConsoleServerPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
|
||||
device = NestedDeviceSerializer()
|
||||
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')
|
||||
device = NestedDeviceSerializer()
|
||||
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')
|
||||
device = NestedDeviceSerializer()
|
||||
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')
|
||||
device = NestedDeviceSerializer()
|
||||
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')
|
||||
device = NestedDeviceSerializer()
|
||||
module = ComponentNestedModuleSerializer(
|
||||
@ -768,7 +768,7 @@ class InterfaceSerializer(PrimaryModelSerializer, LinkTerminationSerializer, Con
|
||||
return super().validate(data)
|
||||
|
||||
|
||||
class RearPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer):
|
||||
class RearPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
|
||||
device = NestedDeviceSerializer()
|
||||
module = ComponentNestedModuleSerializer(
|
||||
@ -798,7 +798,7 @@ class FrontPortRearPortSerializer(WritableNestedSerializer):
|
||||
fields = ['id', 'url', 'display', 'name', 'label']
|
||||
|
||||
|
||||
class FrontPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer):
|
||||
class FrontPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail')
|
||||
device = NestedDeviceSerializer()
|
||||
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')
|
||||
device = NestedDeviceSerializer()
|
||||
# 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')
|
||||
device = NestedDeviceSerializer()
|
||||
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')
|
||||
device = NestedDeviceSerializer()
|
||||
parent = serializers.PrimaryKeyRelatedField(queryset=InventoryItem.objects.all(), allow_null=True, default=None)
|
||||
@ -879,7 +879,7 @@ class InventoryItemSerializer(PrimaryModelSerializer):
|
||||
# Device component roles
|
||||
#
|
||||
|
||||
class InventoryItemRoleSerializer(PrimaryModelSerializer):
|
||||
class InventoryItemRoleSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:inventoryitemrole-detail')
|
||||
inventoryitem_count = serializers.IntegerField(read_only=True)
|
||||
|
||||
@ -895,7 +895,7 @@ class InventoryItemRoleSerializer(PrimaryModelSerializer):
|
||||
# Cables
|
||||
#
|
||||
|
||||
class CableSerializer(PrimaryModelSerializer):
|
||||
class CableSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail')
|
||||
termination_a_type = ContentTypeField(
|
||||
queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)
|
||||
@ -1001,7 +1001,7 @@ class CablePathSerializer(serializers.ModelSerializer):
|
||||
# Virtual chassis
|
||||
#
|
||||
|
||||
class VirtualChassisSerializer(PrimaryModelSerializer):
|
||||
class VirtualChassisSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualchassis-detail')
|
||||
master = NestedDeviceSerializer(required=False)
|
||||
member_count = serializers.IntegerField(read_only=True)
|
||||
@ -1018,7 +1018,7 @@ class VirtualChassisSerializer(PrimaryModelSerializer):
|
||||
# Power panels
|
||||
#
|
||||
|
||||
class PowerPanelSerializer(PrimaryModelSerializer):
|
||||
class PowerPanelSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerpanel-detail')
|
||||
site = NestedSiteSerializer()
|
||||
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')
|
||||
power_panel = NestedPowerPanelSerializer()
|
||||
rack = NestedRackSerializer(
|
||||
|
@ -9,7 +9,7 @@ from ipam.choices import *
|
||||
from ipam.constants import IPADDRESS_ASSIGNMENT_MODELS, VLANGROUP_SCOPE_TYPES
|
||||
from ipam.models import *
|
||||
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 utilities.api import get_serializer_for_model
|
||||
from virtualization.api.nested_serializers import NestedVirtualMachineSerializer
|
||||
@ -20,7 +20,7 @@ from .nested_serializers import *
|
||||
# ASNs
|
||||
#
|
||||
|
||||
class ASNSerializer(PrimaryModelSerializer):
|
||||
class ASNSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:asn-detail')
|
||||
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
||||
site_count = serializers.IntegerField(read_only=True)
|
||||
@ -37,7 +37,7 @@ class ASNSerializer(PrimaryModelSerializer):
|
||||
# VRFs
|
||||
#
|
||||
|
||||
class VRFSerializer(PrimaryModelSerializer):
|
||||
class VRFSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail')
|
||||
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
||||
import_targets = SerializedPKRelatedField(
|
||||
@ -67,7 +67,7 @@ class VRFSerializer(PrimaryModelSerializer):
|
||||
# Route targets
|
||||
#
|
||||
|
||||
class RouteTargetSerializer(PrimaryModelSerializer):
|
||||
class RouteTargetSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:routetarget-detail')
|
||||
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
||||
|
||||
@ -82,7 +82,7 @@ class RouteTargetSerializer(PrimaryModelSerializer):
|
||||
# RIRs/aggregates
|
||||
#
|
||||
|
||||
class RIRSerializer(PrimaryModelSerializer):
|
||||
class RIRSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:rir-detail')
|
||||
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')
|
||||
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
|
||||
rir = NestedRIRSerializer()
|
||||
@ -113,7 +113,7 @@ class AggregateSerializer(PrimaryModelSerializer):
|
||||
# FHRP Groups
|
||||
#
|
||||
|
||||
class FHRPGroupSerializer(PrimaryModelSerializer):
|
||||
class FHRPGroupSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:fhrpgroup-detail')
|
||||
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')
|
||||
group = NestedFHRPGroupSerializer()
|
||||
interface_type = ContentTypeField(
|
||||
@ -153,7 +153,7 @@ class FHRPGroupAssignmentSerializer(PrimaryModelSerializer):
|
||||
# VLANs
|
||||
#
|
||||
|
||||
class RoleSerializer(PrimaryModelSerializer):
|
||||
class RoleSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:role-detail')
|
||||
prefix_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')
|
||||
scope_type = ContentTypeField(
|
||||
queryset=ContentType.objects.filter(
|
||||
@ -196,7 +196,7 @@ class VLANGroupSerializer(PrimaryModelSerializer):
|
||||
return serializer(obj.scope, context=context).data
|
||||
|
||||
|
||||
class VLANSerializer(PrimaryModelSerializer):
|
||||
class VLANSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
|
||||
site = NestedSiteSerializer(required=False, allow_null=True)
|
||||
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)
|
||||
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
||||
status = ChoiceField(choices=VLANStatusChoices, required=False)
|
||||
@ -251,7 +251,7 @@ class CreateAvailableVLANSerializer(PrimaryModelSerializer):
|
||||
# Prefixes
|
||||
#
|
||||
|
||||
class PrefixSerializer(PrimaryModelSerializer):
|
||||
class PrefixSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:prefix-detail')
|
||||
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
|
||||
site = NestedSiteSerializer(required=False, allow_null=True)
|
||||
@ -323,7 +323,7 @@ class AvailablePrefixSerializer(serializers.Serializer):
|
||||
# IP ranges
|
||||
#
|
||||
|
||||
class IPRangeSerializer(PrimaryModelSerializer):
|
||||
class IPRangeSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:iprange-detail')
|
||||
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
|
||||
vrf = NestedVRFSerializer(required=False, allow_null=True)
|
||||
@ -345,7 +345,7 @@ class IPRangeSerializer(PrimaryModelSerializer):
|
||||
# IP addresses
|
||||
#
|
||||
|
||||
class IPAddressSerializer(PrimaryModelSerializer):
|
||||
class IPAddressSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
|
||||
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
|
||||
vrf = NestedVRFSerializer(required=False, allow_null=True)
|
||||
@ -403,7 +403,7 @@ class AvailableIPSerializer(serializers.Serializer):
|
||||
# Services
|
||||
#
|
||||
|
||||
class ServiceTemplateSerializer(PrimaryModelSerializer):
|
||||
class ServiceTemplateSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:servicetemplate-detail')
|
||||
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')
|
||||
device = NestedDeviceSerializer(required=False, allow_null=True)
|
||||
virtual_machine = NestedVirtualMachineSerializer(required=False, allow_null=True)
|
||||
|
@ -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()
|
27
netbox/netbox/api/serializers/__init__.py
Normal file
27
netbox/netbox/api/serializers/__init__.py
Normal 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()
|
43
netbox/netbox/api/serializers/base.py
Normal file
43
netbox/netbox/api/serializers/base.py
Normal 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
|
80
netbox/netbox/api/serializers/features.py
Normal file
80
netbox/netbox/api/serializers/features.py
Normal 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
|
62
netbox/netbox/api/serializers/nested.py
Normal file
62
netbox/netbox/api/serializers/nested.py
Normal 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']
|
@ -3,7 +3,7 @@ from drf_yasg.utils import swagger_serializer_method
|
||||
from rest_framework import serializers
|
||||
|
||||
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.models import *
|
||||
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')
|
||||
group = NestedTenantGroupSerializer(required=False, allow_null=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')
|
||||
|
||||
class Meta:
|
||||
@ -77,7 +77,7 @@ class ContactRoleSerializer(PrimaryModelSerializer):
|
||||
]
|
||||
|
||||
|
||||
class ContactSerializer(PrimaryModelSerializer):
|
||||
class ContactSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:contact-detail')
|
||||
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')
|
||||
content_type = ContentTypeField(
|
||||
queryset=ContentType.objects.all()
|
||||
|
@ -6,7 +6,7 @@ from dcim.choices import InterfaceModeChoices
|
||||
from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer, NestedVRFSerializer
|
||||
from ipam.models import VLAN
|
||||
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 virtualization.choices import *
|
||||
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||
@ -17,7 +17,7 @@ from .nested_serializers import *
|
||||
# Clusters
|
||||
#
|
||||
|
||||
class ClusterTypeSerializer(PrimaryModelSerializer):
|
||||
class ClusterTypeSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustertype-detail')
|
||||
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')
|
||||
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')
|
||||
type = NestedClusterTypeSerializer()
|
||||
group = NestedClusterGroupSerializer(required=False, allow_null=True, default=None)
|
||||
@ -62,7 +62,7 @@ class ClusterSerializer(PrimaryModelSerializer):
|
||||
# Virtual machines
|
||||
#
|
||||
|
||||
class VirtualMachineSerializer(PrimaryModelSerializer):
|
||||
class VirtualMachineSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:virtualmachine-detail')
|
||||
status = ChoiceField(choices=VirtualMachineStatusChoices, required=False)
|
||||
site = NestedSiteSerializer(read_only=True)
|
||||
@ -103,7 +103,7 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer):
|
||||
# VM interfaces
|
||||
#
|
||||
|
||||
class VMInterfaceSerializer(PrimaryModelSerializer):
|
||||
class VMInterfaceSerializer(NetBoxModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:vminterface-detail')
|
||||
virtual_machine = NestedVirtualMachineSerializer()
|
||||
parent = NestedVMInterfaceSerializer(required=False, allow_null=True)
|
||||
|
@ -4,7 +4,7 @@ from dcim.choices import LinkStatusChoices
|
||||
from dcim.api.serializers import NestedInterfaceSerializer
|
||||
from ipam.api.serializers import NestedVLANSerializer
|
||||
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.models 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')
|
||||
group = NestedWirelessLANGroupSerializer(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')
|
||||
status = ChoiceField(choices=LinkStatusChoices, required=False)
|
||||
interface_a = NestedInterfaceSerializer()
|
||||
|
Reference in New Issue
Block a user