Implemented static writable ModelSerializers for all models

This commit is contained in:
Jeremy Stretch 2017-01-31 15:35:09 -05:00
parent e1cd846c9a
commit bb1f97abc2
13 changed files with 251 additions and 140 deletions

View File

@ -2,7 +2,7 @@ from rest_framework import serializers
from circuits.models import Provider, Circuit, CircuitTermination, CircuitType from circuits.models import Provider, Circuit, CircuitTermination, CircuitType
from dcim.api.serializers import NestedSiteSerializer, DeviceInterfaceSerializer from dcim.api.serializers import NestedSiteSerializer, DeviceInterfaceSerializer
from extras.api.serializers import CustomFieldSerializer from extras.api.serializers import CustomFieldValueSerializer
from tenancy.api.serializers import NestedTenantSerializer from tenancy.api.serializers import NestedTenantSerializer
@ -10,17 +10,18 @@ from tenancy.api.serializers import NestedTenantSerializer
# Providers # Providers
# #
class ProviderSerializer(CustomFieldSerializer, serializers.ModelSerializer): class ProviderSerializer(serializers.ModelSerializer):
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = Provider model = Provider
fields = [ fields = [
'id', 'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments', 'id', 'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments',
'custom_fields', 'custom_field_values',
] ]
class NestedProviderSerializer(serializers.HyperlinkedModelSerializer): class NestedProviderSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provider-detail') url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provider-detail')
class Meta: class Meta:
@ -28,6 +29,15 @@ class NestedProviderSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'name', 'slug'] fields = ['id', 'url', 'name', 'slug']
class WritableProviderSerializer(serializers.ModelSerializer):
class Meta:
model = Provider
fields = [
'id', 'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments',
]
# #
# Circuit types # Circuit types
# #
@ -39,7 +49,7 @@ class CircuitTypeSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class NestedCircuitTypeSerializer(serializers.HyperlinkedModelSerializer): class NestedCircuitTypeSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittype-detail') url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittype-detail')
class Meta: class Meta:
@ -64,20 +74,21 @@ class CircuitTerminationSerializer(serializers.ModelSerializer):
# Circuits # Circuits
# #
class CircuitSerializer(CustomFieldSerializer, serializers.ModelSerializer): class CircuitSerializer(serializers.ModelSerializer):
provider = NestedProviderSerializer() provider = NestedProviderSerializer()
type = NestedCircuitTypeSerializer() type = NestedCircuitTypeSerializer()
tenant = NestedTenantSerializer() tenant = NestedTenantSerializer()
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = Circuit model = Circuit
fields = [ fields = [
'id', 'cid', 'provider', 'type', 'tenant', 'install_date', 'commit_rate', 'description', 'comments', 'id', 'cid', 'provider', 'type', 'tenant', 'install_date', 'commit_rate', 'description', 'comments',
'custom_fields', 'custom_field_values',
] ]
class NestedCircuitSerializer(serializers.HyperlinkedModelSerializer): class NestedCircuitSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail') url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail')
class Meta: class Meta:
@ -85,12 +96,10 @@ class NestedCircuitSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'cid'] fields = ['id', 'url', 'cid']
# TODO: Delete this class WritableCircuitSerializer(serializers.ModelSerializer):
class CircuitDetailSerializer(CircuitSerializer):
terminations = CircuitTerminationSerializer(many=True)
class Meta(CircuitSerializer.Meta): class Meta:
model = Circuit
fields = [ fields = [
'id', 'cid', 'provider', 'type', 'tenant', 'install_date', 'commit_rate', 'description', 'comments', 'id', 'cid', 'provider', 'type', 'tenant', 'install_date', 'commit_rate', 'description', 'comments',
'terminations', 'custom_fields',
] ]

View File

@ -2,9 +2,6 @@ from django.conf.urls import include, url
from rest_framework import routers from rest_framework import routers
from extras.models import GRAPH_TYPE_PROVIDER
from extras.api.views import GraphListView
from . import views from . import views

View File

@ -21,9 +21,10 @@ from . import serializers
# Providers # Providers
# #
class ProviderViewSet(CustomFieldModelViewSet): class ProviderViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Provider.objects.all() queryset = Provider.objects.all()
serializer_class = serializers.ProviderSerializer serializer_class = serializers.ProviderSerializer
write_serializer_class = serializers.WritableProviderSerializer
@detail_route() @detail_route()
def graphs(self, request, pk=None): def graphs(self, request, pk=None):
@ -49,6 +50,7 @@ class CircuitTypeViewSet(ModelViewSet):
class CircuitViewSet(WritableSerializerMixin, CustomFieldModelViewSet): class CircuitViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Circuit.objects.select_related('type', 'tenant', 'provider') queryset = Circuit.objects.select_related('type', 'tenant', 'provider')
serializer_class = serializers.CircuitSerializer serializer_class = serializers.CircuitSerializer
write_serializer_class = serializers.WritableCircuitSerializer
filter_class = CircuitFilter filter_class = CircuitFilter

View File

@ -4,10 +4,10 @@ from ipam.models import IPAddress
from dcim.models import ( from dcim.models import (
ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay, DeviceType, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay, DeviceType,
DeviceRole, Interface, InterfaceConnection, InterfaceTemplate, Manufacturer, Module, Platform, PowerOutlet, DeviceRole, Interface, InterfaceConnection, InterfaceTemplate, Manufacturer, Module, Platform, PowerOutlet,
PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, RackGroup, RackRole, RACK_FACE_FRONT, RACK_FACE_REAR, Site, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, RackGroup, RackRole, Site, SUBDEVICE_ROLE_CHILD,
SUBDEVICE_ROLE_CHILD, SUBDEVICE_ROLE_PARENT, SUBDEVICE_ROLE_PARENT,
) )
from extras.api.serializers import CustomFieldSerializer from extras.api.serializers import CustomFieldValueSerializer
from tenancy.api.serializers import NestedTenantSerializer from tenancy.api.serializers import NestedTenantSerializer
@ -15,19 +15,20 @@ from tenancy.api.serializers import NestedTenantSerializer
# Sites # Sites
# #
class SiteSerializer(CustomFieldSerializer, serializers.ModelSerializer): class SiteSerializer(serializers.ModelSerializer):
tenant = NestedTenantSerializer() tenant = NestedTenantSerializer()
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = Site model = Site
fields = [ fields = [
'id', 'name', 'slug', 'tenant', 'facility', 'asn', 'physical_address', 'shipping_address', 'contact_name', 'id', 'name', 'slug', 'tenant', 'facility', 'asn', 'physical_address', 'shipping_address', 'contact_name',
'contact_phone', 'contact_email', 'comments', 'custom_fields', 'count_prefixes', 'count_vlans', 'contact_phone', 'contact_email', 'comments', 'custom_field_values', 'count_prefixes', 'count_vlans',
'count_racks', 'count_devices', 'count_circuits', 'count_racks', 'count_devices', 'count_circuits',
] ]
class NestedSiteSerializer(serializers.HyperlinkedModelSerializer): class NestedSiteSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail')
class Meta: class Meta:
@ -35,6 +36,16 @@ class NestedSiteSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'name', 'slug'] fields = ['id', 'url', 'name', 'slug']
class WritableSiteSerializer(serializers.ModelSerializer):
class Meta:
model = Site
fields = [
'id', 'name', 'slug', 'tenant', 'facility', 'asn', 'physical_address', 'shipping_address', 'contact_name',
'contact_phone', 'contact_email', 'comments',
]
# #
# Rack groups # Rack groups
# #
@ -47,7 +58,7 @@ class RackGroupSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug', 'site'] fields = ['id', 'name', 'slug', 'site']
class NestedRackGroupSerializer(serializers.HyperlinkedModelSerializer): class NestedRackGroupSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackgroup-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackgroup-detail')
class Meta: class Meta:
@ -55,6 +66,13 @@ class NestedRackGroupSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'name', 'slug'] fields = ['id', 'url', 'name', 'slug']
class WritableRackGroupSerializer(serializers.ModelSerializer):
class Meta:
model = RackGroup
fields = ['id', 'name', 'slug', 'site']
# #
# Rack roles # Rack roles
# #
@ -66,7 +84,7 @@ class RackRoleSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug', 'color'] fields = ['id', 'name', 'slug', 'color']
class NestedRackRoleSerializer(serializers.HyperlinkedModelSerializer): class NestedRackRoleSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail')
class Meta: class Meta:
@ -79,21 +97,22 @@ class NestedRackRoleSerializer(serializers.HyperlinkedModelSerializer):
# #
class RackSerializer(CustomFieldSerializer, serializers.ModelSerializer): class RackSerializer(serializers.ModelSerializer):
site = NestedSiteSerializer() site = NestedSiteSerializer()
group = NestedRackGroupSerializer() group = NestedRackGroupSerializer()
tenant = NestedTenantSerializer() tenant = NestedTenantSerializer()
role = NestedRackRoleSerializer() role = NestedRackRoleSerializer()
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = Rack model = Rack
fields = [ fields = [
'id', 'name', 'facility_id', 'display_name', 'site', 'group', 'tenant', 'role', 'type', 'width', 'u_height', 'id', 'name', 'facility_id', 'display_name', 'site', 'group', 'tenant', 'role', 'type', 'width', 'u_height',
'desc_units', 'comments', 'custom_fields', 'desc_units', 'comments', 'custom_field_values',
] ]
class NestedRackSerializer(serializers.HyperlinkedModelSerializer): class NestedRackSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail')
class Meta: class Meta:
@ -101,28 +120,15 @@ class NestedRackSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'name', 'display_name'] fields = ['id', 'url', 'name', 'display_name']
class RackDetailSerializer(RackSerializer): class WritableRackSerializer(serializers.ModelSerializer):
front_units = serializers.SerializerMethodField()
rear_units = serializers.SerializerMethodField()
class Meta(RackSerializer.Meta): class Meta:
model = Rack
fields = [ fields = [
'id', 'name', 'facility_id', 'display_name', 'site', 'group', 'tenant', 'role', 'type', 'width', 'u_height', 'id', 'name', 'facility_id', 'site', 'group', 'tenant', 'role', 'type', 'width', 'u_height', 'desc_units',
'desc_units', 'comments', 'custom_fields', 'front_units', 'rear_units', 'comments',
] ]
def get_front_units(self, obj):
units = obj.get_rack_units(face=RACK_FACE_FRONT)
for u in units:
u['device'] = NestedDeviceSerializer(u['device']).data if u['device'] else None
return units
def get_rear_units(self, obj):
units = obj.get_rack_units(face=RACK_FACE_REAR)
for u in units:
u['device'] = NestedDeviceSerializer(u['device']).data if u['device'] else None
return units
# #
# Manufacturers # Manufacturers
@ -135,7 +141,7 @@ class ManufacturerSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class NestedManufacturerSerializer(serializers.HyperlinkedModelSerializer): class NestedManufacturerSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail')
class Meta: class Meta:
@ -147,16 +153,17 @@ class NestedManufacturerSerializer(serializers.HyperlinkedModelSerializer):
# Device types # Device types
# #
class DeviceTypeSerializer(CustomFieldSerializer, serializers.ModelSerializer): class DeviceTypeSerializer(serializers.ModelSerializer):
manufacturer = NestedManufacturerSerializer() manufacturer = NestedManufacturerSerializer()
subdevice_role = serializers.SerializerMethodField() subdevice_role = serializers.SerializerMethodField()
instance_count = serializers.IntegerField(source='instances.count', read_only=True) instance_count = serializers.IntegerField(source='instances.count', read_only=True)
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = DeviceType model = DeviceType
fields = [ fields = [
'id', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'interface_ordering', 'id', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'interface_ordering',
'is_console_server', 'is_pdu', 'is_network_device', 'subdevice_role', 'comments', 'custom_fields', 'is_console_server', 'is_pdu', 'is_network_device', 'subdevice_role', 'comments', 'custom_field_values',
'instance_count', 'instance_count',
] ]
@ -168,7 +175,7 @@ class DeviceTypeSerializer(CustomFieldSerializer, serializers.ModelSerializer):
}[obj.subdevice_role] }[obj.subdevice_role]
class NestedDeviceTypeSerializer(serializers.HyperlinkedModelSerializer): class NestedDeviceTypeSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail')
manufacturer = NestedManufacturerSerializer() manufacturer = NestedManufacturerSerializer()
@ -177,6 +184,16 @@ class NestedDeviceTypeSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'manufacturer', 'model', 'slug'] fields = ['id', 'url', 'manufacturer', 'model', 'slug']
class WritableDeviceTypeSerializer(serializers.ModelSerializer):
class Meta:
model = DeviceType
fields = [
'id', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'interface_ordering',
'is_console_server', 'is_pdu', 'is_network_device', 'subdevice_role', 'comments',
]
class ConsolePortTemplateSerializer(serializers.ModelSerializer): class ConsolePortTemplateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
@ -230,7 +247,7 @@ class DeviceRoleSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug', 'color'] fields = ['id', 'name', 'slug', 'color']
class NestedDeviceRoleSerializer(serializers.HyperlinkedModelSerializer): class NestedDeviceRoleSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
class Meta: class Meta:
@ -249,7 +266,7 @@ class PlatformSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug', 'rpc_client'] fields = ['id', 'name', 'slug', 'rpc_client']
class NestedPlatformSerializer(serializers.HyperlinkedModelSerializer): class NestedPlatformSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail')
class Meta: class Meta:
@ -262,7 +279,7 @@ class NestedPlatformSerializer(serializers.HyperlinkedModelSerializer):
# #
# Cannot import ipam.api.NestedIPAddressSerializer due to circular dependency # Cannot import ipam.api.NestedIPAddressSerializer due to circular dependency
class DeviceIPAddressSerializer(serializers.HyperlinkedModelSerializer): class DeviceIPAddressSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
class Meta: class Meta:
@ -270,7 +287,7 @@ class DeviceIPAddressSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'family', 'address'] fields = ['id', 'url', 'family', 'address']
class DeviceSerializer(CustomFieldSerializer, serializers.ModelSerializer): class DeviceSerializer(serializers.ModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
device_role = NestedDeviceRoleSerializer() device_role = NestedDeviceRoleSerializer()
tenant = NestedTenantSerializer() tenant = NestedTenantSerializer()
@ -280,13 +297,14 @@ class DeviceSerializer(CustomFieldSerializer, serializers.ModelSerializer):
primary_ip4 = DeviceIPAddressSerializer() primary_ip4 = DeviceIPAddressSerializer()
primary_ip6 = DeviceIPAddressSerializer() primary_ip6 = DeviceIPAddressSerializer()
parent_device = serializers.SerializerMethodField() parent_device = serializers.SerializerMethodField()
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = Device model = Device
fields = [ fields = [
'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6',
'comments', 'custom_fields', 'comments', 'custom_field_values',
] ]
def get_parent_device(self, obj): def get_parent_device(self, obj):
@ -304,7 +322,7 @@ class DeviceSerializer(CustomFieldSerializer, serializers.ModelSerializer):
} }
class NestedDeviceSerializer(serializers.HyperlinkedModelSerializer): class NestedDeviceSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
class Meta: class Meta:
@ -312,19 +330,29 @@ class NestedDeviceSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'name', 'display_name'] fields = ['id', 'url', 'name', 'display_name']
class WritableDeviceSerializer(serializers.ModelSerializer):
class Meta:
model = Device
fields = [
'id', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'rack',
'position', 'face', 'status', 'primary_ip4', 'primary_ip6', 'comments',
]
# #
# Console server ports # Console server ports
# #
class ConsoleServerPortSerializer(serializers.ModelSerializer): class ConsoleServerPortSerializer(serializers.ModelSerializer):
device = NestedDeviceSerializer() device = NestedDeviceSerializer(read_only=True)
class Meta: class Meta:
model = ConsoleServerPort model = ConsoleServerPort
fields = ['id', 'device', 'name', 'connected_console'] fields = ['id', 'device', 'name', 'connected_console']
class DeviceConsoleServerPortSerializer(serializers.HyperlinkedModelSerializer): class DeviceConsoleServerPortSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
class Meta: class Meta:
@ -338,7 +366,7 @@ class DeviceConsoleServerPortSerializer(serializers.HyperlinkedModelSerializer):
# #
class ConsolePortSerializer(serializers.ModelSerializer): class ConsolePortSerializer(serializers.ModelSerializer):
device = NestedDeviceSerializer() device = NestedDeviceSerializer(read_only=True)
cs_port = ConsoleServerPortSerializer() cs_port = ConsoleServerPortSerializer()
class Meta: class Meta:
@ -346,7 +374,7 @@ class ConsolePortSerializer(serializers.ModelSerializer):
fields = ['id', 'device', 'name', 'cs_port', 'connection_status'] fields = ['id', 'device', 'name', 'cs_port', 'connection_status']
class DeviceConsolePortSerializer(serializers.HyperlinkedModelSerializer): class DeviceConsolePortSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail')
class Meta: class Meta:
@ -360,14 +388,14 @@ class DeviceConsolePortSerializer(serializers.HyperlinkedModelSerializer):
# #
class PowerOutletSerializer(serializers.ModelSerializer): class PowerOutletSerializer(serializers.ModelSerializer):
device = NestedDeviceSerializer() device = NestedDeviceSerializer(read_only=True)
class Meta: class Meta:
model = PowerOutlet model = PowerOutlet
fields = ['id', 'device', 'name', 'connected_port'] fields = ['id', 'device', 'name', 'connected_port']
class DevicePowerOutletSerializer(serializers.HyperlinkedModelSerializer): class DevicePowerOutletSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail')
class Meta: class Meta:
@ -381,7 +409,7 @@ class DevicePowerOutletSerializer(serializers.HyperlinkedModelSerializer):
# #
class PowerPortSerializer(serializers.ModelSerializer): class PowerPortSerializer(serializers.ModelSerializer):
device = NestedDeviceSerializer() device = NestedDeviceSerializer(read_only=True)
power_outlet = PowerOutletSerializer() power_outlet = PowerOutletSerializer()
class Meta: class Meta:
@ -389,7 +417,7 @@ class PowerPortSerializer(serializers.ModelSerializer):
fields = ['id', 'device', 'name', 'power_outlet', 'connection_status'] fields = ['id', 'device', 'name', 'power_outlet', 'connection_status']
class DevicePowerPortSerializer(serializers.HyperlinkedModelSerializer): class DevicePowerPortSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail')
class Meta: class Meta:
@ -404,7 +432,7 @@ class DevicePowerPortSerializer(serializers.HyperlinkedModelSerializer):
class InterfaceSerializer(serializers.ModelSerializer): class InterfaceSerializer(serializers.ModelSerializer):
device = NestedDeviceSerializer() device = NestedDeviceSerializer(read_only=True)
connection = serializers.SerializerMethodField(read_only=True) connection = serializers.SerializerMethodField(read_only=True)
connected_interface = serializers.SerializerMethodField(read_only=True) connected_interface = serializers.SerializerMethodField(read_only=True)
@ -426,7 +454,7 @@ class InterfaceSerializer(serializers.ModelSerializer):
return None return None
class PeerInterfaceSerializer(serializers.HyperlinkedModelSerializer): class PeerInterfaceSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
@ -435,7 +463,7 @@ class PeerInterfaceSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'device', 'name', 'form_factor', 'mac_address', 'mgmt_only', 'description'] fields = ['id', 'url', 'device', 'name', 'form_factor', 'mac_address', 'mgmt_only', 'description']
class DeviceInterfaceSerializer(serializers.HyperlinkedModelSerializer): class DeviceInterfaceSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
connection = serializers.SerializerMethodField() connection = serializers.SerializerMethodField()
@ -462,7 +490,7 @@ class InterfaceConnectionSerializer(serializers.ModelSerializer):
fields = ['id', 'interface_a', 'interface_b', 'connection_status'] fields = ['id', 'interface_a', 'interface_b', 'connection_status']
class NestedInterfaceConnectionSerializer(serializers.HyperlinkedModelSerializer): class NestedInterfaceConnectionSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interfaceconnection-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interfaceconnection-detail')
class Meta: class Meta:
@ -470,12 +498,19 @@ class NestedInterfaceConnectionSerializer(serializers.HyperlinkedModelSerializer
fields = ['id', 'url', 'connection_status'] fields = ['id', 'url', 'connection_status']
class WritableInterfaceConnectionSerializer(serializers.ModelSerializer):
class Meta:
model = InterfaceConnection
fields = ['id', 'interface_a', 'interface_b', 'connection_status']
# #
# Device bays # Device bays
# #
class DeviceBaySerializer(serializers.ModelSerializer): class DeviceBaySerializer(serializers.ModelSerializer):
device = NestedDeviceSerializer() device = NestedDeviceSerializer(read_only=True)
installed_device = NestedDeviceSerializer() installed_device = NestedDeviceSerializer()
class Meta: class Meta:
@ -483,7 +518,7 @@ class DeviceBaySerializer(serializers.ModelSerializer):
fields = ['id', 'device', 'name', 'installed_device'] fields = ['id', 'device', 'name', 'installed_device']
class DeviceDeviceBaySerializer(serializers.HyperlinkedModelSerializer): class DeviceDeviceBaySerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebay-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebay-detail')
class Meta: class Meta:
@ -497,7 +532,7 @@ class DeviceDeviceBaySerializer(serializers.HyperlinkedModelSerializer):
# #
class ModuleSerializer(serializers.ModelSerializer): class ModuleSerializer(serializers.ModelSerializer):
device = NestedDeviceSerializer() device = NestedDeviceSerializer(read_only=True)
manufacturer = NestedManufacturerSerializer() manufacturer = NestedManufacturerSerializer()
class Meta: class Meta:
@ -505,7 +540,7 @@ class ModuleSerializer(serializers.ModelSerializer):
fields = ['id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'discovered'] fields = ['id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'discovered']
class DeviceModuleSerializer(serializers.HyperlinkedModelSerializer): class DeviceModuleSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:module-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:module-detail')
manufacturer = NestedManufacturerSerializer() manufacturer = NestedManufacturerSerializer()

View File

@ -2,10 +2,8 @@ from django.conf.urls import include, url
from rest_framework import routers from rest_framework import routers
from extras.models import GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE from extras.api.views import TopologyMapView
from extras.api.views import GraphListView, TopologyMapView
from ipam.api.views import ServiceViewSet, DeviceServiceViewSet from ipam.api.views import ServiceViewSet, DeviceServiceViewSet
from . import views from . import views

View File

@ -33,6 +33,7 @@ from . import serializers
class SiteViewSet(WritableSerializerMixin, CustomFieldModelViewSet): class SiteViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Site.objects.select_related('tenant') queryset = Site.objects.select_related('tenant')
serializer_class = serializers.SiteSerializer serializer_class = serializers.SiteSerializer
write_serializer_class = serializers.WritableSiteSerializer
@detail_route() @detail_route()
def graphs(self, request, pk=None): def graphs(self, request, pk=None):
@ -50,6 +51,7 @@ class RackGroupViewSet(WritableSerializerMixin, ModelViewSet):
queryset = RackGroup.objects.select_related('site') queryset = RackGroup.objects.select_related('site')
serializer_class = serializers.RackGroupSerializer serializer_class = serializers.RackGroupSerializer
filter_class = filters.RackGroupFilter filter_class = filters.RackGroupFilter
write_serializer_class = serializers.WritableRackGroupSerializer
# #
@ -68,6 +70,7 @@ class RackRoleViewSet(ModelViewSet):
class RackViewSet(WritableSerializerMixin, CustomFieldModelViewSet): class RackViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Rack.objects.select_related('site', 'group__site', 'tenant') queryset = Rack.objects.select_related('site', 'group__site', 'tenant')
serializer_class = serializers.RackSerializer serializer_class = serializers.RackSerializer
write_serializer_class = serializers.WritableRackSerializer
filter_class = filters.RackFilter filter_class = filters.RackFilter
@detail_route(url_path='rack-units') @detail_route(url_path='rack-units')
@ -112,6 +115,7 @@ class ManufacturerViewSet(ModelViewSet):
class DeviceTypeViewSet(WritableSerializerMixin, CustomFieldModelViewSet): class DeviceTypeViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = DeviceType.objects.select_related('manufacturer') queryset = DeviceType.objects.select_related('manufacturer')
serializer_class = serializers.DeviceTypeSerializer serializer_class = serializers.DeviceTypeSerializer
write_serializer_class = serializers.WritableDeviceTypeSerializer
# #
@ -143,6 +147,7 @@ class DeviceViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'primary_ip4__nat_outside', 'primary_ip6__nat_outside',
) )
serializer_class = serializers.DeviceSerializer serializer_class = serializers.DeviceSerializer
write_serializer_class = serializers.WritableDeviceSerializer
filter_class = filters.DeviceFilter filter_class = filters.DeviceFilter
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES + [BINDZoneRenderer, FlatJSONRenderer] renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES + [BINDZoneRenderer, FlatJSONRenderer]
@ -335,9 +340,10 @@ class DeviceModuleViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
# Interface connections # Interface connections
# #
class InterfaceConnectionViewSet(ModelViewSet): class InterfaceConnectionViewSet(WritableSerializerMixin, ModelViewSet):
queryset = InterfaceConnection.objects.select_related('interface_a__device', 'interface_b__device') queryset = InterfaceConnection.objects.select_related('interface_a__device', 'interface_b__device')
serializer_class = serializers.InterfaceConnectionSerializer serializer_class = serializers.InterfaceConnectionSerializer
write_serializer_class = serializers.WritableInterfaceConnectionSerializer
# #

View File

@ -1,35 +1,42 @@
from rest_framework import serializers from rest_framework import serializers
from extras.models import CF_TYPE_SELECT, CustomFieldChoice, Graph from extras.models import CF_TYPE_SELECT, CustomFieldChoice, CustomFieldValue, Graph
class CustomFieldSerializer(serializers.Serializer): # class CustomFieldSerializer(serializers.ModelSerializer):
""" # """
Extends a ModelSerializer to render any CustomFields and their values associated with an object. # Extends ModelSerializer to render any CustomFields and their values associated with an object.
""" # """
custom_fields = serializers.SerializerMethodField() # custom_fields = serializers.SerializerMethodField()
#
# def get_custom_fields(self, obj):
#
# # Gather all CustomFields applicable to this object
# fields = {cf.name: None for cf in self.context['custom_fields']}
# custom_field_choices = self.context['custom_field_choices']
#
# # Attach any defined CustomFieldValues to their respective CustomFields
# for cfv in obj.custom_field_values.all():
#
# # Attempt to suppress database lookups for CustomFieldChoices by using the cached choice set from the view
# # context.
# if cfv.field.type == CF_TYPE_SELECT:
# cfc = {
# 'id': int(cfv.serialized_value),
# 'value': custom_field_choices[int(cfv.serialized_value)]
# }
# fields[cfv.field.name] = CustomFieldChoiceSerializer(instance=cfc).data
# else:
# fields[cfv.field.name] = cfv.value
#
# return fields
def get_custom_fields(self, obj):
# Gather all CustomFields applicable to this object class CustomFieldValueSerializer(serializers.ModelSerializer):
fields = {cf.name: None for cf in self.context['custom_fields']}
custom_field_choices = self.context['custom_field_choices']
# Attach any defined CustomFieldValues to their respective CustomFields class Meta:
for cfv in obj.custom_field_values.all(): model = CustomFieldValue
fields = ['field', 'serialized_value']
# Attempt to suppress database lookups for CustomFieldChoices by using the cached choice set from the view
# context.
if cfv.field.type == CF_TYPE_SELECT:
cfc = {
'id': int(cfv.serialized_value),
'value': custom_field_choices[int(cfv.serialized_value)]
}
fields[cfv.field.name] = CustomFieldChoiceSerializer(instance=cfc).data
else:
fields[cfv.field.name] = cfv.value
return fields
class CustomFieldChoiceSerializer(serializers.ModelSerializer): class CustomFieldChoiceSerializer(serializers.ModelSerializer):

View File

@ -1,25 +1,25 @@
from rest_framework import serializers from rest_framework import serializers
from dcim.api.serializers import NestedDeviceSerializer, DeviceInterfaceSerializer, NestedSiteSerializer from dcim.api.serializers import NestedDeviceSerializer, DeviceInterfaceSerializer, NestedSiteSerializer
from extras.api.serializers import CustomFieldSerializer 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, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
from tenancy.api.serializers import NestedTenantSerializer from tenancy.api.serializers import NestedTenantSerializer
from utilities.api import WritableSerializerMixin
# #
# VRFs # VRFs
# #
class VRFSerializer(CustomFieldSerializer, serializers.ModelSerializer): class VRFSerializer(serializers.ModelSerializer):
tenant = NestedTenantSerializer() tenant = NestedTenantSerializer()
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = VRF model = VRF
fields = ['id', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'custom_fields'] fields = ['id', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'custom_field_values']
class NestedVRFSerializer(serializers.HyperlinkedModelSerializer): class NestedVRFSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail')
class Meta: class Meta:
@ -27,6 +27,13 @@ class NestedVRFSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'name', 'rd'] fields = ['id', 'url', 'name', 'rd']
class WritableVRFSerializer(serializers.ModelSerializer):
class Meta:
model = VRF
fields = ['id', 'name', 'rd', 'tenant', 'enforce_unique', 'description']
# #
# Roles # Roles
# #
@ -38,7 +45,7 @@ class RoleSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug', 'weight'] fields = ['id', 'name', 'slug', 'weight']
class NestedRoleSerializer(serializers.HyperlinkedModelSerializer): class NestedRoleSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:role-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:role-detail')
class Meta: class Meta:
@ -57,7 +64,7 @@ class RIRSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug', 'is_private'] fields = ['id', 'name', 'slug', 'is_private']
class NestedRIRSerializer(serializers.HyperlinkedModelSerializer): class NestedRIRSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:rir-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:rir-detail')
class Meta: class Meta:
@ -69,15 +76,16 @@ class NestedRIRSerializer(serializers.HyperlinkedModelSerializer):
# Aggregates # Aggregates
# #
class AggregateSerializer(CustomFieldSerializer, serializers.ModelSerializer): class AggregateSerializer(serializers.ModelSerializer):
rir = NestedRIRSerializer() rir = NestedRIRSerializer()
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = Aggregate model = Aggregate
fields = ['id', 'family', 'prefix', 'rir', 'date_added', 'description', 'custom_fields'] fields = ['id', 'family', 'prefix', 'rir', 'date_added', 'description', 'custom_field_values']
class NestedAggregateSerializer(serializers.HyperlinkedModelSerializer): class NestedAggregateSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:aggregate-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:aggregate-detail')
class Meta(AggregateSerializer.Meta): class Meta(AggregateSerializer.Meta):
@ -85,11 +93,18 @@ class NestedAggregateSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'family', 'prefix'] fields = ['id', 'url', 'family', 'prefix']
class WritableAggregateSerializer(serializers.ModelSerializer):
class Meta:
model = Aggregate
fields = ['id', 'family', 'prefix', 'rir', 'date_added', 'description']
# #
# VLAN groups # VLAN groups
# #
class VLANGroupSerializer(WritableSerializerMixin, serializers.ModelSerializer): class VLANGroupSerializer(serializers.ModelSerializer):
site = NestedSiteSerializer() site = NestedSiteSerializer()
class Meta: class Meta:
@ -97,7 +112,7 @@ class VLANGroupSerializer(WritableSerializerMixin, serializers.ModelSerializer):
fields = ['id', 'name', 'slug', 'site'] fields = ['id', 'name', 'slug', 'site']
class NestedVLANGroupSerializer(serializers.HyperlinkedModelSerializer): class NestedVLANGroupSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlangroup-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlangroup-detail')
class Meta: class Meta:
@ -105,25 +120,33 @@ class NestedVLANGroupSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'name', 'slug'] fields = ['id', 'url', 'name', 'slug']
class WritableVLANGroupSerializer(serializers.ModelSerializer):
class Meta:
model = VLANGroup
fields = ['id', 'name', 'slug', 'site']
# #
# VLANs # VLANs
# #
class VLANSerializer(CustomFieldSerializer, serializers.ModelSerializer): class VLANSerializer(serializers.ModelSerializer):
site = NestedSiteSerializer() site = NestedSiteSerializer()
group = NestedVLANGroupSerializer() group = NestedVLANGroupSerializer()
tenant = NestedTenantSerializer() tenant = NestedTenantSerializer()
role = NestedRoleSerializer() role = NestedRoleSerializer()
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = VLAN model = VLAN
fields = [ fields = [
'id', 'site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description', 'display_name', 'id', 'site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description', 'display_name',
'custom_fields', 'custom_field_values',
] ]
class NestedVLANSerializer(serializers.HyperlinkedModelSerializer): class NestedVLANSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
class Meta: class Meta:
@ -131,26 +154,36 @@ class NestedVLANSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'vid', 'name', 'display_name'] fields = ['id', 'url', 'vid', 'name', 'display_name']
class WritableVLANSerializer(serializers.ModelSerializer):
class Meta:
model = VLAN
fields = [
'id', 'site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description',
]
# #
# Prefixes # Prefixes
# #
class PrefixSerializer(CustomFieldSerializer, serializers.ModelSerializer): class PrefixSerializer(serializers.ModelSerializer):
site = NestedSiteSerializer() site = NestedSiteSerializer()
vrf = NestedVRFSerializer() vrf = NestedVRFSerializer()
tenant = NestedTenantSerializer() tenant = NestedTenantSerializer()
vlan = NestedVLANSerializer() vlan = NestedVLANSerializer()
role = NestedRoleSerializer() role = NestedRoleSerializer()
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = Prefix model = Prefix
fields = [ fields = [
'id', 'family', 'prefix', 'site', 'vrf', 'tenant', 'vlan', 'status', 'role', 'is_pool', 'description', 'id', 'family', 'prefix', 'site', 'vrf', 'tenant', 'vlan', 'status', 'role', 'is_pool', 'description',
'custom_fields', 'custom_field_values',
] ]
class NestedPrefixSerializer(serializers.HyperlinkedModelSerializer): class NestedPrefixSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:prefix-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:prefix-detail')
class Meta: class Meta:
@ -158,24 +191,34 @@ class NestedPrefixSerializer(serializers.HyperlinkedModelSerializer):
fields = ['id', 'url', 'family', 'prefix'] fields = ['id', 'url', 'family', 'prefix']
class WritablePrefixSerializer(serializers.ModelSerializer):
class Meta:
model = Prefix
fields = [
'id', 'family', 'prefix', 'site', 'vrf', 'tenant', 'vlan', 'status', 'role', 'is_pool', 'description',
]
# #
# IP addresses # IP addresses
# #
class IPAddressSerializer(CustomFieldSerializer, serializers.ModelSerializer): class IPAddressSerializer(serializers.ModelSerializer):
vrf = NestedVRFSerializer() vrf = NestedVRFSerializer()
tenant = NestedTenantSerializer() tenant = NestedTenantSerializer()
interface = DeviceInterfaceSerializer() interface = DeviceInterfaceSerializer()
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = IPAddress model = IPAddress
fields = [ fields = [
'id', 'family', 'address', 'vrf', 'tenant', 'status', 'interface', 'description', 'nat_inside', 'id', 'family', 'address', 'vrf', 'tenant', 'status', 'interface', 'description', 'nat_inside',
'nat_outside', 'custom_fields', 'nat_outside', 'custom_field_values',
] ]
class NestedIPAddressSerializer(serializers.HyperlinkedModelSerializer): class NestedIPAddressSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
class Meta: class Meta:
@ -186,6 +229,13 @@ IPAddressSerializer._declared_fields['nat_inside'] = NestedIPAddressSerializer()
IPAddressSerializer._declared_fields['nat_outside'] = NestedIPAddressSerializer() IPAddressSerializer._declared_fields['nat_outside'] = NestedIPAddressSerializer()
class WritableIPAddressSerializer(serializers.ModelSerializer):
class Meta:
model = IPAddress
fields = ['id', 'family', 'address', 'vrf', 'tenant', 'status', 'interface', 'description', 'nat_inside']
# #
# Services # Services
# #
@ -199,7 +249,7 @@ class ServiceSerializer(serializers.ModelSerializer):
fields = ['id', 'device', 'name', 'port', 'protocol', 'ipaddresses', 'description'] fields = ['id', 'device', 'name', 'port', 'protocol', 'ipaddresses', 'description']
class DeviceServiceSerializer(serializers.HyperlinkedModelSerializer): class DeviceServiceSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:service-detail') url = serializers.HyperlinkedIdentityField(view_name='ipam-api:service-detail')
ipaddresses = NestedIPAddressSerializer(many=True) ipaddresses = NestedIPAddressSerializer(many=True)

View File

@ -20,6 +20,7 @@ from . import serializers
class VRFViewSet(WritableSerializerMixin, CustomFieldModelViewSet): class VRFViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = VRF.objects.select_related('tenant') queryset = VRF.objects.select_related('tenant')
serializer_class = serializers.VRFSerializer serializer_class = serializers.VRFSerializer
write_serializer_class = serializers.WritableVRFSerializer
filter_class = filters.VRFFilter filter_class = filters.VRFFilter
@ -48,6 +49,7 @@ class RIRViewSet(ModelViewSet):
class AggregateViewSet(WritableSerializerMixin, CustomFieldModelViewSet): class AggregateViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Aggregate.objects.select_related('rir') queryset = Aggregate.objects.select_related('rir')
serializer_class = serializers.AggregateSerializer serializer_class = serializers.AggregateSerializer
write_serializer_class = serializers.WritableAggregateSerializer
filter_class = filters.AggregateFilter filter_class = filters.AggregateFilter
@ -58,6 +60,7 @@ class AggregateViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
class PrefixViewSet(WritableSerializerMixin, CustomFieldModelViewSet): class PrefixViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Prefix.objects.select_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role') queryset = Prefix.objects.select_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
serializer_class = serializers.PrefixSerializer serializer_class = serializers.PrefixSerializer
write_serializer_class = serializers.WritablePrefixSerializer
filter_class = filters.PrefixFilter filter_class = filters.PrefixFilter
@ -68,6 +71,7 @@ class PrefixViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
class IPAddressViewSet(WritableSerializerMixin, CustomFieldModelViewSet): class IPAddressViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant', 'interface__device', 'nat_inside') queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant', 'interface__device', 'nat_inside')
serializer_class = serializers.IPAddressSerializer serializer_class = serializers.IPAddressSerializer
write_serializer_class = serializers.WritableIPAddressSerializer
filter_class = filters.IPAddressFilter filter_class = filters.IPAddressFilter
@ -78,6 +82,7 @@ class IPAddressViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
class VLANGroupViewSet(WritableSerializerMixin, ModelViewSet): class VLANGroupViewSet(WritableSerializerMixin, ModelViewSet):
queryset = VLANGroup.objects.select_related('site') queryset = VLANGroup.objects.select_related('site')
serializer_class = serializers.VLANGroupSerializer serializer_class = serializers.VLANGroupSerializer
write_serializer_class = serializers.WritableVLANGroupSerializer
filter_class = filters.VLANGroupFilter filter_class = filters.VLANGroupFilter
@ -88,6 +93,7 @@ class VLANGroupViewSet(WritableSerializerMixin, ModelViewSet):
class VLANViewSet(WritableSerializerMixin, CustomFieldModelViewSet): class VLANViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = VLAN.objects.select_related('site', 'group', 'tenant', 'role') queryset = VLAN.objects.select_related('site', 'group', 'tenant', 'role')
serializer_class = serializers.VLANSerializer serializer_class = serializers.VLANSerializer
write_serializer_class = serializers.WritableVLANSerializer
filter_class = filters.VLANFilter filter_class = filters.VLANFilter

View File

@ -15,7 +15,7 @@ class SecretRoleSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class NestedSecretRoleSerializer(serializers.HyperlinkedModelSerializer): class NestedSecretRoleSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='secrets-api:secretrole-detail') url = serializers.HyperlinkedIdentityField(view_name='secrets-api:secretrole-detail')
class Meta: class Meta:

View File

@ -1,6 +1,6 @@
from rest_framework import serializers from rest_framework import serializers
from extras.api.serializers import CustomFieldSerializer from extras.api.serializers import CustomFieldValueSerializer
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
@ -15,7 +15,7 @@ class TenantGroupSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class NestedTenantGroupSerializer(serializers.HyperlinkedModelSerializer): class NestedTenantGroupSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenantgroup-detail') url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenantgroup-detail')
class Meta: class Meta:
@ -27,17 +27,25 @@ class NestedTenantGroupSerializer(serializers.HyperlinkedModelSerializer):
# Tenants # Tenants
# #
class TenantSerializer(CustomFieldSerializer, serializers.ModelSerializer): class TenantSerializer(serializers.ModelSerializer):
group = NestedTenantGroupSerializer() group = NestedTenantGroupSerializer()
custom_field_values = CustomFieldValueSerializer(many=True)
class Meta: class Meta:
model = Tenant model = Tenant
fields = ['id', 'name', 'slug', 'group', 'description', 'comments', 'custom_fields'] fields = ['id', 'name', 'slug', 'group', 'description', 'comments', 'custom_field_values']
class NestedTenantSerializer(serializers.HyperlinkedModelSerializer): class NestedTenantSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenant-detail') url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenant-detail')
class Meta: class Meta:
model = Tenant model = Tenant
fields = ['id', 'url', 'name', 'slug'] fields = ['id', 'url', 'name', 'slug']
class WritableTenantSerializer(serializers.ModelSerializer):
class Meta:
model = Tenant
fields = ['id', 'name', 'slug', 'group', 'description', 'comments']

View File

@ -24,4 +24,5 @@ class TenantGroupViewSet(ModelViewSet):
class TenantViewSet(WritableSerializerMixin, CustomFieldModelViewSet): class TenantViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Tenant.objects.select_related('group') queryset = Tenant.objects.select_related('group')
serializer_class = serializers.TenantSerializer serializer_class = serializers.TenantSerializer
write_serializer_class = serializers.WritableTenantSerializer
filter_class = TenantFilter filter_class = TenantFilter

View File

@ -12,18 +12,10 @@ class ServiceUnavailable(APIException):
class WritableSerializerMixin(object): class WritableSerializerMixin(object):
""" """
Returns a flat Serializer from the given model suitable for write operations (POST, PUT, PATCH). This is necessary Allow for the use of an alternate, writable serializer class for write operations (e.g. POST, PUT).
to allow write operations on objects which utilize nested serializers.
""" """
def get_serializer_class(self): def get_serializer_class(self):
if self.action in WRITE_OPERATIONS and hasattr(self, 'write_serializer_class'):
class WritableSerializer(ModelSerializer): return self.write_serializer_class
class Meta(self.serializer_class.Meta):
pass
if self.action in WRITE_OPERATIONS:
return WritableSerializer
return self.serializer_class return self.serializer_class