diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 41c4eaf9a..c2b7bbd81 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -2,13 +2,15 @@ from rest_framework import serializers from ipam.models import IPAddress from dcim.models import ( - ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay, - DeviceBayTemplate, DeviceType, DeviceRole, Interface, InterfaceConnection, InterfaceTemplate, Manufacturer, Module, - Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, RackGroup, RackRole, Site, - SUBDEVICE_ROLE_CHILD, SUBDEVICE_ROLE_PARENT, + CONNECTION_STATUS_CHOICES, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, + DeviceBay, DeviceBayTemplate, DeviceType, DeviceRole, IFACE_FF_CHOICES, IFACE_ORDERING_CHOICES, Interface, + InterfaceConnection, InterfaceTemplate, Manufacturer, Module, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, + PowerPortTemplate, Rack, RackGroup, RackRole, RACK_FACE_CHOICES, RACK_TYPE_CHOICES, RACK_WIDTH_CHOICES, Site, + STATUS_CHOICES, SUBDEVICE_ROLE_CHOICES, ) from extras.api.serializers import CustomFieldValueSerializer from tenancy.api.serializers import NestedTenantSerializer +from utilities.api import ChoiceFieldSerializer # @@ -102,6 +104,8 @@ class RackSerializer(serializers.ModelSerializer): group = NestedRackGroupSerializer() tenant = NestedTenantSerializer() role = NestedRackRoleSerializer() + type = ChoiceFieldSerializer(choices=RACK_TYPE_CHOICES) + width = ChoiceFieldSerializer(choices=RACK_WIDTH_CHOICES) custom_field_values = CustomFieldValueSerializer(many=True) class Meta: @@ -155,7 +159,8 @@ class NestedManufacturerSerializer(serializers.ModelSerializer): class DeviceTypeSerializer(serializers.ModelSerializer): manufacturer = NestedManufacturerSerializer() - subdevice_role = serializers.SerializerMethodField() + interface_ordering = ChoiceFieldSerializer(choices=IFACE_ORDERING_CHOICES) + subdevice_role = ChoiceFieldSerializer(choices=SUBDEVICE_ROLE_CHOICES) instance_count = serializers.IntegerField(source='instances.count', read_only=True) custom_field_values = CustomFieldValueSerializer(many=True) @@ -167,13 +172,6 @@ class DeviceTypeSerializer(serializers.ModelSerializer): 'instance_count', ] - def get_subdevice_role(self, obj): - return { - SUBDEVICE_ROLE_PARENT: 'parent', - SUBDEVICE_ROLE_CHILD: 'child', - None: None, - }[obj.subdevice_role] - class NestedDeviceTypeSerializer(serializers.ModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail') @@ -276,6 +274,7 @@ class WritablePowerOutletTemplateSerializer(serializers.ModelSerializer): class InterfaceTemplateSerializer(serializers.ModelSerializer): device_type = NestedDeviceTypeSerializer() + form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES) class Meta: model = InterfaceTemplate @@ -365,6 +364,8 @@ class DeviceSerializer(serializers.ModelSerializer): tenant = NestedTenantSerializer() platform = NestedPlatformSerializer() rack = NestedRackSerializer() + face = ChoiceFieldSerializer(choices=RACK_FACE_CHOICES) + status = ChoiceFieldSerializer(choices=STATUS_CHOICES) primary_ip = DeviceIPAddressSerializer() primary_ip4 = DeviceIPAddressSerializer() primary_ip6 = DeviceIPAddressSerializer() @@ -497,6 +498,7 @@ class WritablePowerPortSerializer(serializers.ModelSerializer): class InterfaceSerializer(serializers.ModelSerializer): device = NestedDeviceSerializer() + form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES) connection = serializers.SerializerMethodField(read_only=True) connected_interface = serializers.SerializerMethodField(read_only=True) @@ -581,6 +583,7 @@ class WritableModuleSerializer(serializers.ModelSerializer): class InterfaceConnectionSerializer(serializers.ModelSerializer): interface_a = PeerInterfaceSerializer() interface_b = PeerInterfaceSerializer() + connection_status = ChoiceFieldSerializer(choices=CONNECTION_STATUS_CHOICES) class Meta: model = InterfaceConnection diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index bf7cf6e49..86688f82c 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -2,8 +2,12 @@ from rest_framework import serializers from dcim.api.serializers import NestedDeviceSerializer, InterfaceSerializer, NestedSiteSerializer from extras.api.serializers import CustomFieldValueSerializer -from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF +from ipam.models import ( + Aggregate, IPAddress, IPADDRESS_STATUS_CHOICES, IP_PROTOCOL_CHOICES, Prefix, PREFIX_STATUS_CHOICES, RIR, Role, + Service, VLAN, VLAN_STATUS_CHOICES, VLANGroup, VRF, +) from tenancy.api.serializers import NestedTenantSerializer +from utilities.api import ChoiceFieldSerializer # @@ -135,6 +139,7 @@ class VLANSerializer(serializers.ModelSerializer): site = NestedSiteSerializer() group = NestedVLANGroupSerializer() tenant = NestedTenantSerializer() + status = ChoiceFieldSerializer(choices=VLAN_STATUS_CHOICES) role = NestedRoleSerializer() custom_field_values = CustomFieldValueSerializer(many=True) @@ -172,6 +177,7 @@ class PrefixSerializer(serializers.ModelSerializer): vrf = NestedVRFSerializer() tenant = NestedTenantSerializer() vlan = NestedVLANSerializer() + status = ChoiceFieldSerializer(choices=PREFIX_STATUS_CHOICES) role = NestedRoleSerializer() custom_field_values = CustomFieldValueSerializer(many=True) @@ -207,6 +213,7 @@ class WritablePrefixSerializer(serializers.ModelSerializer): class IPAddressSerializer(serializers.ModelSerializer): vrf = NestedVRFSerializer() tenant = NestedTenantSerializer() + status = ChoiceFieldSerializer(choices=IPADDRESS_STATUS_CHOICES) interface = InterfaceSerializer() custom_field_values = CustomFieldValueSerializer(many=True) @@ -242,6 +249,7 @@ class WritableIPAddressSerializer(serializers.ModelSerializer): class ServiceSerializer(serializers.ModelSerializer): device = NestedDeviceSerializer() + protocol = ChoiceFieldSerializer(choices=IP_PROTOCOL_CHOICES) ipaddresses = NestedIPAddressSerializer(many=True) class Meta: diff --git a/netbox/utilities/api.py b/netbox/utilities/api.py index 818eb8289..a44fadb0c 100644 --- a/netbox/utilities/api.py +++ b/netbox/utilities/api.py @@ -1,5 +1,5 @@ from rest_framework.exceptions import APIException -from rest_framework.serializers import ModelSerializer +from rest_framework.serializers import Field WRITE_OPERATIONS = ['create', 'update', 'partial_update', 'delete'] @@ -10,6 +10,22 @@ class ServiceUnavailable(APIException): default_detail = "Service temporarily unavailable, please try again later." +class ChoiceFieldSerializer(Field): + """ + Represent a ChoiceField as a list of (value, label) tuples. + """ + + def __init__(self, choices, **kwargs): + self._choices = choices + super(ChoiceFieldSerializer, self).__init__(**kwargs) + + def to_representation(self, obj): + return self._choices[obj] + + def to_internal_value(self, data): + return getattr(self._choices, data) + + class WritableSerializerMixin(object): """ Allow for the use of an alternate, writable serializer class for write operations (e.g. POST, PUT).