mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 20:12:00 -06:00
Started merging writable serializers (WIP)
This commit is contained in:
parent
db3cbaf83b
commit
7241783249
@ -7,7 +7,7 @@ from circuits.models import Provider, Circuit, CircuitTermination, CircuitType
|
||||
from dcim.api.serializers import NestedSiteSerializer, InterfaceSerializer
|
||||
from extras.api.customfields import CustomFieldModelSerializer
|
||||
from tenancy.api.serializers import NestedTenantSerializer
|
||||
from utilities.api import ChoiceFieldSerializer, ValidatedModelSerializer
|
||||
from utilities.api import ChoiceFieldSerializer, ValidatedModelSerializer, WritableNestedSerializer
|
||||
|
||||
|
||||
#
|
||||
@ -24,7 +24,7 @@ class ProviderSerializer(CustomFieldModelSerializer):
|
||||
]
|
||||
|
||||
|
||||
class NestedProviderSerializer(serializers.ModelSerializer):
|
||||
class NestedProviderSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provider-detail')
|
||||
|
||||
class Meta:
|
||||
@ -32,16 +32,6 @@ class NestedProviderSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'url', 'name', 'slug']
|
||||
|
||||
|
||||
class WritableProviderSerializer(CustomFieldModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Provider
|
||||
fields = [
|
||||
'id', 'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments',
|
||||
'custom_fields', 'created', 'last_updated',
|
||||
]
|
||||
|
||||
|
||||
#
|
||||
# Circuit types
|
||||
#
|
||||
@ -53,7 +43,7 @@ class CircuitTypeSerializer(ValidatedModelSerializer):
|
||||
fields = ['id', 'name', 'slug']
|
||||
|
||||
|
||||
class NestedCircuitTypeSerializer(serializers.ModelSerializer):
|
||||
class NestedCircuitTypeSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittype-detail')
|
||||
|
||||
class Meta:
|
||||
@ -67,9 +57,9 @@ class NestedCircuitTypeSerializer(serializers.ModelSerializer):
|
||||
|
||||
class CircuitSerializer(CustomFieldModelSerializer):
|
||||
provider = NestedProviderSerializer()
|
||||
status = ChoiceFieldSerializer(choices=CIRCUIT_STATUS_CHOICES)
|
||||
status = ChoiceFieldSerializer(choices=CIRCUIT_STATUS_CHOICES, required=False)
|
||||
type = NestedCircuitTypeSerializer()
|
||||
tenant = NestedTenantSerializer()
|
||||
tenant = NestedTenantSerializer(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Circuit
|
||||
@ -79,7 +69,7 @@ class CircuitSerializer(CustomFieldModelSerializer):
|
||||
]
|
||||
|
||||
|
||||
class NestedCircuitSerializer(serializers.ModelSerializer):
|
||||
class NestedCircuitSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail')
|
||||
|
||||
class Meta:
|
||||
@ -87,33 +77,14 @@ class NestedCircuitSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'url', 'cid']
|
||||
|
||||
|
||||
class WritableCircuitSerializer(CustomFieldModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Circuit
|
||||
fields = [
|
||||
'id', 'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'commit_rate', 'description',
|
||||
'comments', 'custom_fields', 'created', 'last_updated',
|
||||
]
|
||||
|
||||
|
||||
#
|
||||
# Circuit Terminations
|
||||
#
|
||||
|
||||
class CircuitTerminationSerializer(serializers.ModelSerializer):
|
||||
class CircuitTerminationSerializer(ValidatedModelSerializer):
|
||||
circuit = NestedCircuitSerializer()
|
||||
site = NestedSiteSerializer()
|
||||
interface = InterfaceSerializer()
|
||||
|
||||
class Meta:
|
||||
model = CircuitTermination
|
||||
fields = [
|
||||
'id', 'circuit', 'term_side', 'site', 'interface', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info',
|
||||
]
|
||||
|
||||
|
||||
class WritableCircuitTerminationSerializer(ValidatedModelSerializer):
|
||||
interface = InterfaceSerializer(required=False)
|
||||
|
||||
class Meta:
|
||||
model = CircuitTermination
|
||||
|
@ -30,7 +30,6 @@ class CircuitsFieldChoicesViewSet(FieldChoicesViewSet):
|
||||
class ProviderViewSet(CustomFieldModelViewSet):
|
||||
queryset = Provider.objects.all()
|
||||
serializer_class = serializers.ProviderSerializer
|
||||
write_serializer_class = serializers.WritableProviderSerializer
|
||||
filter_class = filters.ProviderFilter
|
||||
|
||||
@detail_route()
|
||||
@ -61,7 +60,6 @@ class CircuitTypeViewSet(ModelViewSet):
|
||||
class CircuitViewSet(CustomFieldModelViewSet):
|
||||
queryset = Circuit.objects.select_related('type', 'tenant', 'provider')
|
||||
serializer_class = serializers.CircuitSerializer
|
||||
write_serializer_class = serializers.WritableCircuitSerializer
|
||||
filter_class = filters.CircuitFilter
|
||||
|
||||
|
||||
@ -72,5 +70,4 @@ class CircuitViewSet(CustomFieldModelViewSet):
|
||||
class CircuitTerminationViewSet(ModelViewSet):
|
||||
queryset = CircuitTermination.objects.select_related('circuit', 'site', 'interface__device')
|
||||
serializer_class = serializers.CircuitTerminationSerializer
|
||||
write_serializer_class = serializers.WritableCircuitTerminationSerializer
|
||||
filter_class = filters.CircuitTerminationFilter
|
||||
|
@ -20,7 +20,7 @@ from extras.api.customfields import CustomFieldModelSerializer
|
||||
from ipam.models import IPAddress, VLAN
|
||||
from tenancy.api.serializers import NestedTenantSerializer
|
||||
from users.api.serializers import NestedUserSerializer
|
||||
from utilities.api import ChoiceFieldSerializer, TimeZoneField, ValidatedModelSerializer
|
||||
from utilities.api import ChoiceFieldSerializer, TimeZoneField, ValidatedModelSerializer, WritableNestedSerializer
|
||||
from virtualization.models import Cluster
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ from virtualization.models import Cluster
|
||||
# Regions
|
||||
#
|
||||
|
||||
class NestedRegionSerializer(serializers.ModelSerializer):
|
||||
class NestedRegionSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:region-detail')
|
||||
|
||||
class Meta:
|
||||
@ -37,14 +37,7 @@ class NestedRegionSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class RegionSerializer(serializers.ModelSerializer):
|
||||
parent = NestedRegionSerializer()
|
||||
|
||||
class Meta:
|
||||
model = Region
|
||||
fields = ['id', 'name', 'slug', 'parent']
|
||||
|
||||
|
||||
class WritableRegionSerializer(ValidatedModelSerializer):
|
||||
parent = NestedRegionSerializer(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Region
|
||||
@ -56,9 +49,9 @@ class WritableRegionSerializer(ValidatedModelSerializer):
|
||||
#
|
||||
|
||||
class SiteSerializer(CustomFieldModelSerializer):
|
||||
status = ChoiceFieldSerializer(choices=SITE_STATUS_CHOICES)
|
||||
region = NestedRegionSerializer()
|
||||
tenant = NestedTenantSerializer()
|
||||
status = ChoiceFieldSerializer(choices=SITE_STATUS_CHOICES, required=False)
|
||||
region = NestedRegionSerializer(required=False)
|
||||
tenant = NestedTenantSerializer(required=False)
|
||||
time_zone = TimeZoneField(required=False)
|
||||
|
||||
class Meta:
|
||||
@ -71,7 +64,7 @@ class SiteSerializer(CustomFieldModelSerializer):
|
||||
]
|
||||
|
||||
|
||||
class NestedSiteSerializer(serializers.ModelSerializer):
|
||||
class NestedSiteSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail')
|
||||
|
||||
class Meta:
|
||||
@ -79,23 +72,11 @@ class NestedSiteSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'url', 'name', 'slug']
|
||||
|
||||
|
||||
class WritableSiteSerializer(CustomFieldModelSerializer):
|
||||
time_zone = TimeZoneField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Site
|
||||
fields = [
|
||||
'id', 'name', 'slug', 'status', 'region', 'tenant', 'facility', 'asn', 'time_zone', 'description',
|
||||
'physical_address', 'shipping_address', 'contact_name', 'contact_phone', 'contact_email', 'comments',
|
||||
'custom_fields', 'created', 'last_updated',
|
||||
]
|
||||
|
||||
|
||||
#
|
||||
# Rack groups
|
||||
#
|
||||
|
||||
class RackGroupSerializer(serializers.ModelSerializer):
|
||||
class RackGroupSerializer(ValidatedModelSerializer):
|
||||
site = NestedSiteSerializer()
|
||||
|
||||
class Meta:
|
||||
@ -103,7 +84,7 @@ class RackGroupSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'name', 'slug', 'site']
|
||||
|
||||
|
||||
class NestedRackGroupSerializer(serializers.ModelSerializer):
|
||||
class NestedRackGroupSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackgroup-detail')
|
||||
|
||||
class Meta:
|
||||
@ -111,13 +92,6 @@ class NestedRackGroupSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'url', 'name', 'slug']
|
||||
|
||||
|
||||
class WritableRackGroupSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = RackGroup
|
||||
fields = ['id', 'name', 'slug', 'site']
|
||||
|
||||
|
||||
#
|
||||
# Rack roles
|
||||
#
|
||||
@ -129,7 +103,7 @@ class RackRoleSerializer(ValidatedModelSerializer):
|
||||
fields = ['id', 'name', 'slug', 'color']
|
||||
|
||||
|
||||
class NestedRackRoleSerializer(serializers.ModelSerializer):
|
||||
class NestedRackRoleSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail')
|
||||
|
||||
class Meta:
|
||||
@ -143,11 +117,11 @@ class NestedRackRoleSerializer(serializers.ModelSerializer):
|
||||
|
||||
class RackSerializer(CustomFieldModelSerializer):
|
||||
site = NestedSiteSerializer()
|
||||
group = NestedRackGroupSerializer()
|
||||
tenant = NestedTenantSerializer()
|
||||
role = NestedRackRoleSerializer()
|
||||
type = ChoiceFieldSerializer(choices=RACK_TYPE_CHOICES)
|
||||
width = ChoiceFieldSerializer(choices=RACK_WIDTH_CHOICES)
|
||||
group = NestedRackGroupSerializer(required=False)
|
||||
tenant = NestedTenantSerializer(required=False)
|
||||
role = NestedRackRoleSerializer(required=False)
|
||||
type = ChoiceFieldSerializer(choices=RACK_TYPE_CHOICES, required=False)
|
||||
width = ChoiceFieldSerializer(choices=RACK_WIDTH_CHOICES, required=False)
|
||||
|
||||
class Meta:
|
||||
model = Rack
|
||||
@ -155,24 +129,6 @@ class RackSerializer(CustomFieldModelSerializer):
|
||||
'id', 'name', 'facility_id', 'display_name', 'site', 'group', 'tenant', 'role', 'serial', 'type', 'width',
|
||||
'u_height', 'desc_units', 'comments', 'custom_fields', 'created', 'last_updated',
|
||||
]
|
||||
|
||||
|
||||
class NestedRackSerializer(serializers.ModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail')
|
||||
|
||||
class Meta:
|
||||
model = Rack
|
||||
fields = ['id', 'url', 'name', 'display_name']
|
||||
|
||||
|
||||
class WritableRackSerializer(CustomFieldModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Rack
|
||||
fields = [
|
||||
'id', 'name', 'facility_id', 'site', 'group', 'tenant', 'role', 'serial', 'type', 'width', 'u_height',
|
||||
'desc_units', 'comments', 'custom_fields', 'created', 'last_updated',
|
||||
]
|
||||
# Omit the UniqueTogetherValidator that would be automatically added to validate (site, facility_id). This
|
||||
# prevents facility_id from being interpreted as a required field.
|
||||
validators = [
|
||||
@ -188,16 +144,24 @@ class WritableRackSerializer(CustomFieldModelSerializer):
|
||||
validator(data)
|
||||
|
||||
# Enforce model validation
|
||||
super(WritableRackSerializer, self).validate(data)
|
||||
super(RackSerializer, self).validate(data)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
class NestedRackSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail')
|
||||
|
||||
class Meta:
|
||||
model = Rack
|
||||
fields = ['id', 'url', 'name', 'display_name']
|
||||
|
||||
|
||||
#
|
||||
# Rack units
|
||||
#
|
||||
|
||||
class NestedDeviceSerializer(serializers.ModelSerializer):
|
||||
class NestedDeviceSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
|
||||
|
||||
class Meta:
|
||||
@ -219,23 +183,16 @@ class RackUnitSerializer(serializers.Serializer):
|
||||
# Rack reservations
|
||||
#
|
||||
|
||||
class RackReservationSerializer(serializers.ModelSerializer):
|
||||
class RackReservationSerializer(ValidatedModelSerializer):
|
||||
rack = NestedRackSerializer()
|
||||
user = NestedUserSerializer()
|
||||
tenant = NestedTenantSerializer()
|
||||
tenant = NestedTenantSerializer(required=False)
|
||||
|
||||
class Meta:
|
||||
model = RackReservation
|
||||
fields = ['id', 'rack', 'units', 'created', 'user', 'tenant', 'description']
|
||||
|
||||
|
||||
class WritableRackReservationSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = RackReservation
|
||||
fields = ['id', 'rack', 'units', 'user', 'description']
|
||||
|
||||
|
||||
#
|
||||
# Manufacturers
|
||||
#
|
||||
@ -247,7 +204,7 @@ class ManufacturerSerializer(ValidatedModelSerializer):
|
||||
fields = ['id', 'name', 'slug']
|
||||
|
||||
|
||||
class NestedManufacturerSerializer(serializers.ModelSerializer):
|
||||
class NestedManufacturerSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail')
|
||||
|
||||
class Meta:
|
||||
@ -261,8 +218,8 @@ class NestedManufacturerSerializer(serializers.ModelSerializer):
|
||||
|
||||
class DeviceTypeSerializer(CustomFieldModelSerializer):
|
||||
manufacturer = NestedManufacturerSerializer()
|
||||
interface_ordering = ChoiceFieldSerializer(choices=IFACE_ORDERING_CHOICES)
|
||||
subdevice_role = ChoiceFieldSerializer(choices=SUBDEVICE_ROLE_CHOICES)
|
||||
interface_ordering = ChoiceFieldSerializer(choices=IFACE_ORDERING_CHOICES, required=False)
|
||||
subdevice_role = ChoiceFieldSerializer(choices=SUBDEVICE_ROLE_CHOICES, required=False)
|
||||
instance_count = serializers.IntegerField(source='instances.count', read_only=True)
|
||||
|
||||
class Meta:
|
||||
@ -274,30 +231,20 @@ class DeviceTypeSerializer(CustomFieldModelSerializer):
|
||||
]
|
||||
|
||||
|
||||
class NestedDeviceTypeSerializer(serializers.ModelSerializer):
|
||||
class NestedDeviceTypeSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail')
|
||||
manufacturer = NestedManufacturerSerializer()
|
||||
manufacturer = NestedManufacturerSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = DeviceType
|
||||
fields = ['id', 'url', 'manufacturer', 'model', 'slug']
|
||||
|
||||
|
||||
class WritableDeviceTypeSerializer(CustomFieldModelSerializer):
|
||||
|
||||
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', 'custom_fields',
|
||||
]
|
||||
|
||||
|
||||
#
|
||||
# Console port templates
|
||||
#
|
||||
|
||||
class ConsolePortTemplateSerializer(serializers.ModelSerializer):
|
||||
class ConsolePortTemplateSerializer(ValidatedModelSerializer):
|
||||
device_type = NestedDeviceTypeSerializer()
|
||||
|
||||
class Meta:
|
||||
@ -305,18 +252,11 @@ class ConsolePortTemplateSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'device_type', 'name']
|
||||
|
||||
|
||||
class WritableConsolePortTemplateSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = ConsolePortTemplate
|
||||
fields = ['id', 'device_type', 'name']
|
||||
|
||||
|
||||
#
|
||||
# Console server port templates
|
||||
#
|
||||
|
||||
class ConsoleServerPortTemplateSerializer(serializers.ModelSerializer):
|
||||
class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
|
||||
device_type = NestedDeviceTypeSerializer()
|
||||
|
||||
class Meta:
|
||||
@ -324,18 +264,11 @@ class ConsoleServerPortTemplateSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'device_type', 'name']
|
||||
|
||||
|
||||
class WritableConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = ConsoleServerPortTemplate
|
||||
fields = ['id', 'device_type', 'name']
|
||||
|
||||
|
||||
#
|
||||
# Power port templates
|
||||
#
|
||||
|
||||
class PowerPortTemplateSerializer(serializers.ModelSerializer):
|
||||
class PowerPortTemplateSerializer(ValidatedModelSerializer):
|
||||
device_type = NestedDeviceTypeSerializer()
|
||||
|
||||
class Meta:
|
||||
@ -343,18 +276,11 @@ class PowerPortTemplateSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'device_type', 'name']
|
||||
|
||||
|
||||
class WritablePowerPortTemplateSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = PowerPortTemplate
|
||||
fields = ['id', 'device_type', 'name']
|
||||
|
||||
|
||||
#
|
||||
# Power outlet templates
|
||||
#
|
||||
|
||||
class PowerOutletTemplateSerializer(serializers.ModelSerializer):
|
||||
class PowerOutletTemplateSerializer(ValidatedModelSerializer):
|
||||
device_type = NestedDeviceTypeSerializer()
|
||||
|
||||
class Meta:
|
||||
@ -362,27 +288,13 @@ class PowerOutletTemplateSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'device_type', 'name']
|
||||
|
||||
|
||||
class WritablePowerOutletTemplateSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = PowerOutletTemplate
|
||||
fields = ['id', 'device_type', 'name']
|
||||
|
||||
|
||||
#
|
||||
# Interface templates
|
||||
#
|
||||
|
||||
class InterfaceTemplateSerializer(serializers.ModelSerializer):
|
||||
class InterfaceTemplateSerializer(ValidatedModelSerializer):
|
||||
device_type = NestedDeviceTypeSerializer()
|
||||
form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES)
|
||||
|
||||
class Meta:
|
||||
model = InterfaceTemplate
|
||||
fields = ['id', 'device_type', 'name', 'form_factor', 'mgmt_only']
|
||||
|
||||
|
||||
class WritableInterfaceTemplateSerializer(ValidatedModelSerializer):
|
||||
form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES, required=False)
|
||||
|
||||
class Meta:
|
||||
model = InterfaceTemplate
|
||||
@ -393,7 +305,7 @@ class WritableInterfaceTemplateSerializer(ValidatedModelSerializer):
|
||||
# Device bay templates
|
||||
#
|
||||
|
||||
class DeviceBayTemplateSerializer(serializers.ModelSerializer):
|
||||
class DeviceBayTemplateSerializer(ValidatedModelSerializer):
|
||||
device_type = NestedDeviceTypeSerializer()
|
||||
|
||||
class Meta:
|
||||
@ -401,13 +313,6 @@ class DeviceBayTemplateSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'device_type', 'name']
|
||||
|
||||
|
||||
class WritableDeviceBayTemplateSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = DeviceBayTemplate
|
||||
fields = ['id', 'device_type', 'name']
|
||||
|
||||
|
||||
#
|
||||
# Device roles
|
||||
#
|
||||
@ -419,7 +324,7 @@ class DeviceRoleSerializer(ValidatedModelSerializer):
|
||||
fields = ['id', 'name', 'slug', 'color', 'vm_role']
|
||||
|
||||
|
||||
class NestedDeviceRoleSerializer(serializers.ModelSerializer):
|
||||
class NestedDeviceRoleSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
|
||||
|
||||
class Meta:
|
||||
@ -431,15 +336,15 @@ class NestedDeviceRoleSerializer(serializers.ModelSerializer):
|
||||
# Platforms
|
||||
#
|
||||
|
||||
class PlatformSerializer(serializers.ModelSerializer):
|
||||
manufacturer = NestedManufacturerSerializer()
|
||||
class PlatformSerializer(ValidatedModelSerializer):
|
||||
manufacturer = NestedManufacturerSerializer(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Platform
|
||||
fields = ['id', 'name', 'slug', 'manufacturer', 'napalm_driver', 'rpc_client']
|
||||
|
||||
|
||||
class NestedPlatformSerializer(serializers.ModelSerializer):
|
||||
class NestedPlatformSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail')
|
||||
|
||||
class Meta:
|
||||
@ -447,13 +352,6 @@ class NestedPlatformSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'url', 'name', 'slug']
|
||||
|
||||
|
||||
class WritablePlatformSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Platform
|
||||
fields = ['id', 'name', 'slug', 'manufacturer', 'napalm_driver', 'rpc_client']
|
||||
|
||||
|
||||
#
|
||||
# Devices
|
||||
#
|
||||
@ -489,18 +387,18 @@ class DeviceVirtualChassisSerializer(serializers.ModelSerializer):
|
||||
class DeviceSerializer(CustomFieldModelSerializer):
|
||||
device_type = NestedDeviceTypeSerializer()
|
||||
device_role = NestedDeviceRoleSerializer()
|
||||
tenant = NestedTenantSerializer()
|
||||
platform = NestedPlatformSerializer()
|
||||
tenant = NestedTenantSerializer(required=False)
|
||||
platform = NestedPlatformSerializer(required=False)
|
||||
site = NestedSiteSerializer()
|
||||
rack = NestedRackSerializer()
|
||||
face = ChoiceFieldSerializer(choices=RACK_FACE_CHOICES)
|
||||
status = ChoiceFieldSerializer(choices=DEVICE_STATUS_CHOICES)
|
||||
primary_ip = DeviceIPAddressSerializer()
|
||||
primary_ip4 = DeviceIPAddressSerializer()
|
||||
primary_ip6 = DeviceIPAddressSerializer()
|
||||
rack = NestedRackSerializer(required=False)
|
||||
face = ChoiceFieldSerializer(choices=RACK_FACE_CHOICES, required=False)
|
||||
status = ChoiceFieldSerializer(choices=DEVICE_STATUS_CHOICES, required=False)
|
||||
primary_ip = DeviceIPAddressSerializer(read_only=True)
|
||||
primary_ip4 = DeviceIPAddressSerializer(required=False)
|
||||
primary_ip6 = DeviceIPAddressSerializer(required=False)
|
||||
parent_device = serializers.SerializerMethodField()
|
||||
cluster = NestedClusterSerializer()
|
||||
virtual_chassis = DeviceVirtualChassisSerializer()
|
||||
cluster = NestedClusterSerializer(required=False)
|
||||
virtual_chassis = DeviceVirtualChassisSerializer(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Device
|
||||
@ -510,27 +408,6 @@ class DeviceSerializer(CustomFieldModelSerializer):
|
||||
'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments', 'custom_fields', 'created',
|
||||
'last_updated',
|
||||
]
|
||||
|
||||
def get_parent_device(self, obj):
|
||||
try:
|
||||
device_bay = obj.parent_bay
|
||||
except DeviceBay.DoesNotExist:
|
||||
return None
|
||||
context = {'request': self.context['request']}
|
||||
data = NestedDeviceSerializer(instance=device_bay.device, context=context).data
|
||||
data['device_bay'] = NestedDeviceBaySerializer(instance=device_bay, context=context).data
|
||||
return data
|
||||
|
||||
|
||||
class WritableDeviceSerializer(CustomFieldModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Device
|
||||
fields = [
|
||||
'id', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'site', 'rack',
|
||||
'position', 'face', 'status', 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position',
|
||||
'vc_priority', 'comments', 'custom_fields', 'created', 'last_updated',
|
||||
]
|
||||
validators = []
|
||||
|
||||
def validate(self, data):
|
||||
@ -542,16 +419,26 @@ class WritableDeviceSerializer(CustomFieldModelSerializer):
|
||||
validator(data)
|
||||
|
||||
# Enforce model validation
|
||||
super(WritableDeviceSerializer, self).validate(data)
|
||||
super(DeviceSerializer, self).validate(data)
|
||||
|
||||
return data
|
||||
|
||||
def get_parent_device(self, obj):
|
||||
try:
|
||||
device_bay = obj.parent_bay
|
||||
except DeviceBay.DoesNotExist:
|
||||
return None
|
||||
context = {'request': self.context['request']}
|
||||
data = NestedDeviceSerializer(instance=device_bay.device, context=context).data
|
||||
data['device_bay'] = NestedDeviceBaySerializer(instance=device_bay, context=context).data
|
||||
return data
|
||||
|
||||
|
||||
#
|
||||
# Console server ports
|
||||
#
|
||||
|
||||
class ConsoleServerPortSerializer(serializers.ModelSerializer):
|
||||
class ConsoleServerPortSerializer(ValidatedModelSerializer):
|
||||
device = NestedDeviceSerializer()
|
||||
|
||||
class Meta:
|
||||
@ -560,27 +447,22 @@ class ConsoleServerPortSerializer(serializers.ModelSerializer):
|
||||
read_only_fields = ['connected_console']
|
||||
|
||||
|
||||
class WritableConsoleServerPortSerializer(ValidatedModelSerializer):
|
||||
class NestedConsoleServerPortSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
|
||||
device = NestedDeviceSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = ConsoleServerPort
|
||||
fields = ['id', 'device', 'name']
|
||||
fields = ['id', 'url', 'device', 'name']
|
||||
|
||||
|
||||
#
|
||||
# Console ports
|
||||
#
|
||||
|
||||
class ConsolePortSerializer(serializers.ModelSerializer):
|
||||
class ConsolePortSerializer(ValidatedModelSerializer):
|
||||
device = NestedDeviceSerializer()
|
||||
cs_port = ConsoleServerPortSerializer()
|
||||
|
||||
class Meta:
|
||||
model = ConsolePort
|
||||
fields = ['id', 'device', 'name', 'cs_port', 'connection_status']
|
||||
|
||||
|
||||
class WritableConsolePortSerializer(ValidatedModelSerializer):
|
||||
cs_port = NestedConsoleServerPortSerializer(required=False)
|
||||
|
||||
class Meta:
|
||||
model = ConsolePort
|
||||
@ -591,7 +473,7 @@ class WritableConsolePortSerializer(ValidatedModelSerializer):
|
||||
# Power outlets
|
||||
#
|
||||
|
||||
class PowerOutletSerializer(serializers.ModelSerializer):
|
||||
class PowerOutletSerializer(ValidatedModelSerializer):
|
||||
device = NestedDeviceSerializer()
|
||||
|
||||
class Meta:
|
||||
@ -600,27 +482,22 @@ class PowerOutletSerializer(serializers.ModelSerializer):
|
||||
read_only_fields = ['connected_port']
|
||||
|
||||
|
||||
class WritablePowerOutletSerializer(ValidatedModelSerializer):
|
||||
class NestedPowerOutletSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail')
|
||||
device = NestedDeviceSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = PowerOutlet
|
||||
fields = ['id', 'device', 'name']
|
||||
fields = ['id', 'url', 'device', 'name']
|
||||
|
||||
|
||||
#
|
||||
# Power ports
|
||||
#
|
||||
|
||||
class PowerPortSerializer(serializers.ModelSerializer):
|
||||
class PowerPortSerializer(ValidatedModelSerializer):
|
||||
device = NestedDeviceSerializer()
|
||||
power_outlet = PowerOutletSerializer()
|
||||
|
||||
class Meta:
|
||||
model = PowerPort
|
||||
fields = ['id', 'device', 'name', 'power_outlet', 'connection_status']
|
||||
|
||||
|
||||
class WritablePowerPortSerializer(ValidatedModelSerializer):
|
||||
power_outlet = NestedPowerOutletSerializer(required=False)
|
||||
|
||||
class Meta:
|
||||
model = PowerPort
|
||||
@ -631,12 +508,13 @@ class WritablePowerPortSerializer(ValidatedModelSerializer):
|
||||
# Interfaces
|
||||
#
|
||||
|
||||
class NestedInterfaceSerializer(serializers.ModelSerializer):
|
||||
class NestedInterfaceSerializer(WritableNestedSerializer):
|
||||
device = NestedDeviceSerializer(read_only=True)
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
|
||||
|
||||
class Meta:
|
||||
model = Interface
|
||||
fields = ['id', 'url', 'name']
|
||||
fields = ['id', 'url', 'device', 'name']
|
||||
|
||||
|
||||
class InterfaceNestedCircuitSerializer(serializers.ModelSerializer):
|
||||
@ -647,8 +525,8 @@ class InterfaceNestedCircuitSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'url', 'cid']
|
||||
|
||||
|
||||
class InterfaceCircuitTerminationSerializer(serializers.ModelSerializer):
|
||||
circuit = InterfaceNestedCircuitSerializer()
|
||||
class InterfaceCircuitTerminationSerializer(WritableNestedSerializer):
|
||||
circuit = InterfaceNestedCircuitSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = CircuitTermination
|
||||
@ -658,7 +536,7 @@ class InterfaceCircuitTerminationSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
# Cannot import ipam.api.NestedVLANSerializer due to circular dependency
|
||||
class InterfaceVLANSerializer(serializers.ModelSerializer):
|
||||
class InterfaceVLANSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
|
||||
|
||||
class Meta:
|
||||
@ -666,16 +544,16 @@ class InterfaceVLANSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'url', 'vid', 'name', 'display_name']
|
||||
|
||||
|
||||
class InterfaceSerializer(serializers.ModelSerializer):
|
||||
class InterfaceSerializer(ValidatedModelSerializer):
|
||||
device = NestedDeviceSerializer()
|
||||
form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES)
|
||||
lag = NestedInterfaceSerializer()
|
||||
form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES, required=False)
|
||||
lag = NestedInterfaceSerializer(required=False)
|
||||
is_connected = serializers.SerializerMethodField(read_only=True)
|
||||
interface_connection = serializers.SerializerMethodField(read_only=True)
|
||||
circuit_termination = InterfaceCircuitTerminationSerializer()
|
||||
untagged_vlan = InterfaceVLANSerializer()
|
||||
mode = ChoiceFieldSerializer(choices=IFACE_MODE_CHOICES)
|
||||
tagged_vlans = InterfaceVLANSerializer(many=True)
|
||||
circuit_termination = InterfaceCircuitTerminationSerializer(required=False)
|
||||
untagged_vlan = InterfaceVLANSerializer(required=False)
|
||||
mode = ChoiceFieldSerializer(choices=IFACE_MODE_CHOICES, required=False)
|
||||
tagged_vlans = InterfaceVLANSerializer(many=True, required=False)
|
||||
|
||||
class Meta:
|
||||
model = Interface
|
||||
@ -684,51 +562,6 @@ class InterfaceSerializer(serializers.ModelSerializer):
|
||||
'is_connected', 'interface_connection', 'circuit_termination', 'mode', 'untagged_vlan', 'tagged_vlans',
|
||||
]
|
||||
|
||||
def get_is_connected(self, obj):
|
||||
"""
|
||||
Return True if the interface has a connected interface or circuit termination.
|
||||
"""
|
||||
if obj.connection:
|
||||
return True
|
||||
try:
|
||||
circuit_termination = obj.circuit_termination
|
||||
return True
|
||||
except CircuitTermination.DoesNotExist:
|
||||
pass
|
||||
return False
|
||||
|
||||
def get_interface_connection(self, obj):
|
||||
if obj.connection:
|
||||
return OrderedDict((
|
||||
('interface', PeerInterfaceSerializer(obj.connected_interface, context=self.context).data),
|
||||
('status', obj.connection.connection_status),
|
||||
))
|
||||
return None
|
||||
|
||||
|
||||
class PeerInterfaceSerializer(serializers.ModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
|
||||
device = NestedDeviceSerializer()
|
||||
form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES)
|
||||
lag = NestedInterfaceSerializer()
|
||||
|
||||
class Meta:
|
||||
model = Interface
|
||||
fields = [
|
||||
'id', 'url', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only',
|
||||
'description',
|
||||
]
|
||||
|
||||
|
||||
class WritableInterfaceSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Interface
|
||||
fields = [
|
||||
'id', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description',
|
||||
'mode', 'untagged_vlan', 'tagged_vlans',
|
||||
]
|
||||
|
||||
def validate(self, data):
|
||||
|
||||
# All associated VLANs be global or assigned to the parent device's site.
|
||||
@ -746,23 +579,58 @@ class WritableInterfaceSerializer(ValidatedModelSerializer):
|
||||
"be global.".format(vlan)
|
||||
})
|
||||
|
||||
return super(WritableInterfaceSerializer, self).validate(data)
|
||||
return super(InterfaceSerializer, self).validate(data)
|
||||
|
||||
def get_is_connected(self, obj):
|
||||
"""
|
||||
Return True if the interface has a connected interface or circuit termination.
|
||||
"""
|
||||
if obj.connection:
|
||||
return True
|
||||
try:
|
||||
circuit_termination = obj.circuit_termination
|
||||
return True
|
||||
except CircuitTermination.DoesNotExist:
|
||||
pass
|
||||
return False
|
||||
|
||||
def get_interface_connection(self, obj):
|
||||
if obj.connection:
|
||||
return OrderedDict((
|
||||
('interface', NestedInterfaceSerializer(obj.connected_interface, context=self.context).data),
|
||||
('status', obj.connection.connection_status),
|
||||
))
|
||||
return None
|
||||
|
||||
|
||||
# class PeerInterfaceSerializer(serializers.ModelSerializer):
|
||||
# url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
|
||||
# device = NestedDeviceSerializer()
|
||||
# form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES)
|
||||
# lag = NestedInterfaceSerializer()
|
||||
#
|
||||
# class Meta:
|
||||
# model = Interface
|
||||
# fields = [
|
||||
# 'id', 'url', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only',
|
||||
# 'description',
|
||||
# ]
|
||||
|
||||
|
||||
#
|
||||
# Device bays
|
||||
#
|
||||
|
||||
class DeviceBaySerializer(serializers.ModelSerializer):
|
||||
class DeviceBaySerializer(ValidatedModelSerializer):
|
||||
device = NestedDeviceSerializer()
|
||||
installed_device = NestedDeviceSerializer()
|
||||
installed_device = NestedDeviceSerializer(required=False)
|
||||
|
||||
class Meta:
|
||||
model = DeviceBay
|
||||
fields = ['id', 'device', 'name', 'installed_device']
|
||||
|
||||
|
||||
class NestedDeviceBaySerializer(serializers.ModelSerializer):
|
||||
class NestedDeviceBaySerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebay-detail')
|
||||
|
||||
class Meta:
|
||||
@ -770,32 +638,15 @@ class NestedDeviceBaySerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'url', 'name']
|
||||
|
||||
|
||||
class WritableDeviceBaySerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = DeviceBay
|
||||
fields = ['id', 'device', 'name', 'installed_device']
|
||||
|
||||
|
||||
#
|
||||
# Inventory items
|
||||
#
|
||||
|
||||
class InventoryItemSerializer(serializers.ModelSerializer):
|
||||
class InventoryItemSerializer(ValidatedModelSerializer):
|
||||
device = NestedDeviceSerializer()
|
||||
manufacturer = NestedManufacturerSerializer()
|
||||
|
||||
class Meta:
|
||||
model = InventoryItem
|
||||
fields = [
|
||||
'id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered',
|
||||
'description',
|
||||
]
|
||||
|
||||
|
||||
class WritableInventoryItemSerializer(ValidatedModelSerializer):
|
||||
# Provide a default value to satisfy UniqueTogetherValidator
|
||||
parent = serializers.PrimaryKeyRelatedField(queryset=InventoryItem.objects.all(), allow_null=True, default=None)
|
||||
manufacturer = NestedManufacturerSerializer()
|
||||
|
||||
class Meta:
|
||||
model = InventoryItem
|
||||
@ -809,17 +660,17 @@ class WritableInventoryItemSerializer(ValidatedModelSerializer):
|
||||
# Interface connections
|
||||
#
|
||||
|
||||
class InterfaceConnectionSerializer(serializers.ModelSerializer):
|
||||
interface_a = PeerInterfaceSerializer()
|
||||
interface_b = PeerInterfaceSerializer()
|
||||
connection_status = ChoiceFieldSerializer(choices=CONNECTION_STATUS_CHOICES)
|
||||
class InterfaceConnectionSerializer(ValidatedModelSerializer):
|
||||
interface_a = NestedInterfaceSerializer()
|
||||
interface_b = NestedInterfaceSerializer()
|
||||
connection_status = ChoiceFieldSerializer(choices=CONNECTION_STATUS_CHOICES, required=False)
|
||||
|
||||
class Meta:
|
||||
model = InterfaceConnection
|
||||
fields = ['id', 'interface_a', 'interface_b', 'connection_status']
|
||||
|
||||
|
||||
class NestedInterfaceConnectionSerializer(serializers.ModelSerializer):
|
||||
class NestedInterfaceConnectionSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interfaceconnection-detail')
|
||||
|
||||
class Meta:
|
||||
@ -827,18 +678,11 @@ class NestedInterfaceConnectionSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'url', 'connection_status']
|
||||
|
||||
|
||||
class WritableInterfaceConnectionSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = InterfaceConnection
|
||||
fields = ['id', 'interface_a', 'interface_b', 'connection_status']
|
||||
|
||||
|
||||
#
|
||||
# Virtual chassis
|
||||
#
|
||||
|
||||
class VirtualChassisSerializer(serializers.ModelSerializer):
|
||||
class VirtualChassisSerializer(ValidatedModelSerializer):
|
||||
master = NestedDeviceSerializer()
|
||||
|
||||
class Meta:
|
||||
@ -846,16 +690,9 @@ class VirtualChassisSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'master', 'domain']
|
||||
|
||||
|
||||
class NestedVirtualChassisSerializer(serializers.ModelSerializer):
|
||||
class NestedVirtualChassisSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualchassis-detail')
|
||||
|
||||
class Meta:
|
||||
model = VirtualChassis
|
||||
fields = ['id', 'url']
|
||||
|
||||
|
||||
class WritableVirtualChassisSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = VirtualChassis
|
||||
fields = ['id', 'master', 'domain']
|
||||
|
@ -52,7 +52,6 @@ class DCIMFieldChoicesViewSet(FieldChoicesViewSet):
|
||||
class RegionViewSet(ModelViewSet):
|
||||
queryset = Region.objects.all()
|
||||
serializer_class = serializers.RegionSerializer
|
||||
write_serializer_class = serializers.WritableRegionSerializer
|
||||
filter_class = filters.RegionFilter
|
||||
|
||||
|
||||
@ -63,7 +62,6 @@ class RegionViewSet(ModelViewSet):
|
||||
class SiteViewSet(CustomFieldModelViewSet):
|
||||
queryset = Site.objects.select_related('region', 'tenant')
|
||||
serializer_class = serializers.SiteSerializer
|
||||
write_serializer_class = serializers.WritableSiteSerializer
|
||||
filter_class = filters.SiteFilter
|
||||
|
||||
@detail_route()
|
||||
@ -84,7 +82,6 @@ class SiteViewSet(CustomFieldModelViewSet):
|
||||
class RackGroupViewSet(ModelViewSet):
|
||||
queryset = RackGroup.objects.select_related('site')
|
||||
serializer_class = serializers.RackGroupSerializer
|
||||
write_serializer_class = serializers.WritableRackGroupSerializer
|
||||
filter_class = filters.RackGroupFilter
|
||||
|
||||
|
||||
@ -105,7 +102,6 @@ class RackRoleViewSet(ModelViewSet):
|
||||
class RackViewSet(CustomFieldModelViewSet):
|
||||
queryset = Rack.objects.select_related('site', 'group__site', 'tenant')
|
||||
serializer_class = serializers.RackSerializer
|
||||
write_serializer_class = serializers.WritableRackSerializer
|
||||
filter_class = filters.RackFilter
|
||||
|
||||
@detail_route()
|
||||
@ -136,7 +132,6 @@ class RackViewSet(CustomFieldModelViewSet):
|
||||
class RackReservationViewSet(ModelViewSet):
|
||||
queryset = RackReservation.objects.select_related('rack', 'user', 'tenant')
|
||||
serializer_class = serializers.RackReservationSerializer
|
||||
write_serializer_class = serializers.WritableRackReservationSerializer
|
||||
filter_class = filters.RackReservationFilter
|
||||
|
||||
# Assign user from request
|
||||
@ -161,7 +156,6 @@ class ManufacturerViewSet(ModelViewSet):
|
||||
class DeviceTypeViewSet(CustomFieldModelViewSet):
|
||||
queryset = DeviceType.objects.select_related('manufacturer')
|
||||
serializer_class = serializers.DeviceTypeSerializer
|
||||
write_serializer_class = serializers.WritableDeviceTypeSerializer
|
||||
filter_class = filters.DeviceTypeFilter
|
||||
|
||||
|
||||
@ -172,42 +166,36 @@ class DeviceTypeViewSet(CustomFieldModelViewSet):
|
||||
class ConsolePortTemplateViewSet(ModelViewSet):
|
||||
queryset = ConsolePortTemplate.objects.select_related('device_type__manufacturer')
|
||||
serializer_class = serializers.ConsolePortTemplateSerializer
|
||||
write_serializer_class = serializers.WritableConsolePortTemplateSerializer
|
||||
filter_class = filters.ConsolePortTemplateFilter
|
||||
|
||||
|
||||
class ConsoleServerPortTemplateViewSet(ModelViewSet):
|
||||
queryset = ConsoleServerPortTemplate.objects.select_related('device_type__manufacturer')
|
||||
serializer_class = serializers.ConsoleServerPortTemplateSerializer
|
||||
write_serializer_class = serializers.WritableConsoleServerPortTemplateSerializer
|
||||
filter_class = filters.ConsoleServerPortTemplateFilter
|
||||
|
||||
|
||||
class PowerPortTemplateViewSet(ModelViewSet):
|
||||
queryset = PowerPortTemplate.objects.select_related('device_type__manufacturer')
|
||||
serializer_class = serializers.PowerPortTemplateSerializer
|
||||
write_serializer_class = serializers.WritablePowerPortTemplateSerializer
|
||||
filter_class = filters.PowerPortTemplateFilter
|
||||
|
||||
|
||||
class PowerOutletTemplateViewSet(ModelViewSet):
|
||||
queryset = PowerOutletTemplate.objects.select_related('device_type__manufacturer')
|
||||
serializer_class = serializers.PowerOutletTemplateSerializer
|
||||
write_serializer_class = serializers.WritablePowerOutletTemplateSerializer
|
||||
filter_class = filters.PowerOutletTemplateFilter
|
||||
|
||||
|
||||
class InterfaceTemplateViewSet(ModelViewSet):
|
||||
queryset = InterfaceTemplate.objects.select_related('device_type__manufacturer')
|
||||
serializer_class = serializers.InterfaceTemplateSerializer
|
||||
write_serializer_class = serializers.WritableInterfaceTemplateSerializer
|
||||
filter_class = filters.InterfaceTemplateFilter
|
||||
|
||||
|
||||
class DeviceBayTemplateViewSet(ModelViewSet):
|
||||
queryset = DeviceBayTemplate.objects.select_related('device_type__manufacturer')
|
||||
serializer_class = serializers.DeviceBayTemplateSerializer
|
||||
write_serializer_class = serializers.WritableDeviceBayTemplateSerializer
|
||||
filter_class = filters.DeviceBayTemplateFilter
|
||||
|
||||
|
||||
@ -228,7 +216,6 @@ class DeviceRoleViewSet(ModelViewSet):
|
||||
class PlatformViewSet(ModelViewSet):
|
||||
queryset = Platform.objects.all()
|
||||
serializer_class = serializers.PlatformSerializer
|
||||
write_serializer_class = serializers.WritablePlatformSerializer
|
||||
filter_class = filters.PlatformFilter
|
||||
|
||||
|
||||
@ -244,7 +231,6 @@ class DeviceViewSet(CustomFieldModelViewSet):
|
||||
'primary_ip4__nat_outside', 'primary_ip6__nat_outside',
|
||||
)
|
||||
serializer_class = serializers.DeviceSerializer
|
||||
write_serializer_class = serializers.WritableDeviceSerializer
|
||||
filter_class = filters.DeviceFilter
|
||||
|
||||
@detail_route(url_path='napalm')
|
||||
@ -318,35 +304,30 @@ class DeviceViewSet(CustomFieldModelViewSet):
|
||||
class ConsolePortViewSet(ModelViewSet):
|
||||
queryset = ConsolePort.objects.select_related('device', 'cs_port__device')
|
||||
serializer_class = serializers.ConsolePortSerializer
|
||||
write_serializer_class = serializers.WritableConsolePortSerializer
|
||||
filter_class = filters.ConsolePortFilter
|
||||
|
||||
|
||||
class ConsoleServerPortViewSet(ModelViewSet):
|
||||
queryset = ConsoleServerPort.objects.select_related('device', 'connected_console__device')
|
||||
serializer_class = serializers.ConsoleServerPortSerializer
|
||||
write_serializer_class = serializers.WritableConsoleServerPortSerializer
|
||||
filter_class = filters.ConsoleServerPortFilter
|
||||
|
||||
|
||||
class PowerPortViewSet(ModelViewSet):
|
||||
queryset = PowerPort.objects.select_related('device', 'power_outlet__device')
|
||||
serializer_class = serializers.PowerPortSerializer
|
||||
write_serializer_class = serializers.WritablePowerPortSerializer
|
||||
filter_class = filters.PowerPortFilter
|
||||
|
||||
|
||||
class PowerOutletViewSet(ModelViewSet):
|
||||
queryset = PowerOutlet.objects.select_related('device', 'connected_port__device')
|
||||
serializer_class = serializers.PowerOutletSerializer
|
||||
write_serializer_class = serializers.WritablePowerOutletSerializer
|
||||
filter_class = filters.PowerOutletFilter
|
||||
|
||||
|
||||
class InterfaceViewSet(ModelViewSet):
|
||||
queryset = Interface.objects.select_related('device')
|
||||
serializer_class = serializers.InterfaceSerializer
|
||||
write_serializer_class = serializers.WritableInterfaceSerializer
|
||||
filter_class = filters.InterfaceFilter
|
||||
|
||||
@detail_route()
|
||||
@ -363,14 +344,12 @@ class InterfaceViewSet(ModelViewSet):
|
||||
class DeviceBayViewSet(ModelViewSet):
|
||||
queryset = DeviceBay.objects.select_related('installed_device')
|
||||
serializer_class = serializers.DeviceBaySerializer
|
||||
write_serializer_class = serializers.WritableDeviceBaySerializer
|
||||
filter_class = filters.DeviceBayFilter
|
||||
|
||||
|
||||
class InventoryItemViewSet(ModelViewSet):
|
||||
queryset = InventoryItem.objects.select_related('device', 'manufacturer')
|
||||
serializer_class = serializers.InventoryItemSerializer
|
||||
write_serializer_class = serializers.WritableInventoryItemSerializer
|
||||
filter_class = filters.InventoryItemFilter
|
||||
|
||||
|
||||
@ -393,7 +372,6 @@ class PowerConnectionViewSet(ListModelMixin, GenericViewSet):
|
||||
class InterfaceConnectionViewSet(ModelViewSet):
|
||||
queryset = InterfaceConnection.objects.select_related('interface_a__device', 'interface_b__device')
|
||||
serializer_class = serializers.InterfaceConnectionSerializer
|
||||
write_serializer_class = serializers.WritableInterfaceConnectionSerializer
|
||||
filter_class = filters.InterfaceConnectionFilter
|
||||
|
||||
|
||||
@ -404,7 +382,6 @@ class InterfaceConnectionViewSet(ModelViewSet):
|
||||
class VirtualChassisViewSet(ModelViewSet):
|
||||
queryset = VirtualChassis.objects.all()
|
||||
serializer_class = serializers.VirtualChassisSerializer
|
||||
write_serializer_class = serializers.WritableVirtualChassisSerializer
|
||||
|
||||
|
||||
#
|
||||
|
@ -1,6 +1,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
@ -2321,6 +2322,7 @@ class InterfaceTest(HttpStatusMixin, APITestCase):
|
||||
self.assertEqual(interface4.device_id, data['device'])
|
||||
self.assertEqual(interface4.name, data['name'])
|
||||
|
||||
@override_settings(DEBUG=True)
|
||||
def test_create_interface_with_802_1q(self):
|
||||
|
||||
data = {
|
||||
@ -2368,6 +2370,7 @@ class InterfaceTest(HttpStatusMixin, APITestCase):
|
||||
self.assertEqual(response.data[1]['name'], data[1]['name'])
|
||||
self.assertEqual(response.data[2]['name'], data[2]['name'])
|
||||
|
||||
@override_settings(DEBUG=True)
|
||||
def test_create_interface_802_1q_bulk(self):
|
||||
|
||||
data = [
|
||||
@ -2852,9 +2855,9 @@ class InterfaceConnectionTest(HttpStatusMixin, APITestCase):
|
||||
|
||||
self.assertHttpStatus(response, status.HTTP_201_CREATED)
|
||||
self.assertEqual(InterfaceConnection.objects.count(), 6)
|
||||
self.assertEqual(response.data[0]['interface_a'], data[0]['interface_a'])
|
||||
self.assertEqual(response.data[1]['interface_a'], data[1]['interface_a'])
|
||||
self.assertEqual(response.data[2]['interface_a'], data[2]['interface_a'])
|
||||
for i in range(0, 3):
|
||||
self.assertEqual(response.data[i]['interface_a']['id'], data[i]['interface_a'])
|
||||
self.assertEqual(response.data[i]['interface_b']['id'], data[i]['interface_b'])
|
||||
|
||||
def test_update_interfaceconnection(self):
|
||||
|
||||
@ -3052,12 +3055,9 @@ class VirtualChassisTest(HttpStatusMixin, APITestCase):
|
||||
response = self.client.post(url, data, format='json', **self.header)
|
||||
self.assertHttpStatus(response, status.HTTP_201_CREATED)
|
||||
self.assertEqual(VirtualChassis.objects.count(), 5)
|
||||
self.assertEqual(response.data[0]['master'], data[0]['master'])
|
||||
self.assertEqual(response.data[0]['domain'], data[0]['domain'])
|
||||
self.assertEqual(response.data[1]['master'], data[1]['master'])
|
||||
self.assertEqual(response.data[1]['domain'], data[1]['domain'])
|
||||
self.assertEqual(response.data[2]['master'], data[2]['master'])
|
||||
self.assertEqual(response.data[2]['domain'], data[2]['domain'])
|
||||
for i in range(0, 3):
|
||||
self.assertEqual(response.data[i]['master']['id'], data[i]['master'])
|
||||
self.assertEqual(response.data[i]['domain'], data[i]['domain'])
|
||||
|
||||
def test_update_virtualchassis(self):
|
||||
|
||||
|
@ -15,7 +15,7 @@ from utilities.api import ChoiceFieldSerializer, ContentTypeFieldSerializer, Val
|
||||
# Graphs
|
||||
#
|
||||
|
||||
class GraphSerializer(serializers.ModelSerializer):
|
||||
class GraphSerializer(ValidatedModelSerializer):
|
||||
type = ChoiceFieldSerializer(choices=GRAPH_TYPE_CHOICES)
|
||||
|
||||
class Meta:
|
||||
@ -23,13 +23,6 @@ class GraphSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'type', 'weight', 'name', 'source', 'link']
|
||||
|
||||
|
||||
class WritableGraphSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Graph
|
||||
fields = ['id', 'type', 'weight', 'name', 'source', 'link']
|
||||
|
||||
|
||||
class RenderedGraphSerializer(serializers.ModelSerializer):
|
||||
embed_url = serializers.SerializerMethodField()
|
||||
embed_link = serializers.SerializerMethodField()
|
||||
@ -50,7 +43,7 @@ class RenderedGraphSerializer(serializers.ModelSerializer):
|
||||
# Export templates
|
||||
#
|
||||
|
||||
class ExportTemplateSerializer(serializers.ModelSerializer):
|
||||
class ExportTemplateSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = ExportTemplate
|
||||
@ -61,7 +54,7 @@ class ExportTemplateSerializer(serializers.ModelSerializer):
|
||||
# Topology maps
|
||||
#
|
||||
|
||||
class TopologyMapSerializer(serializers.ModelSerializer):
|
||||
class TopologyMapSerializer(ValidatedModelSerializer):
|
||||
site = NestedSiteSerializer()
|
||||
|
||||
class Meta:
|
||||
@ -69,23 +62,34 @@ class TopologyMapSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'name', 'slug', 'site', 'device_patterns', 'description']
|
||||
|
||||
|
||||
class WritableTopologyMapSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = TopologyMap
|
||||
fields = ['id', 'name', 'slug', 'site', 'device_patterns', 'description']
|
||||
|
||||
|
||||
#
|
||||
# Image attachments
|
||||
#
|
||||
|
||||
class ImageAttachmentSerializer(serializers.ModelSerializer):
|
||||
parent = serializers.SerializerMethodField()
|
||||
class ImageAttachmentSerializer(ValidatedModelSerializer):
|
||||
content_type = ContentTypeFieldSerializer()
|
||||
parent = serializers.SerializerMethodField(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = ImageAttachment
|
||||
fields = ['id', 'parent', 'name', 'image', 'image_height', 'image_width', 'created']
|
||||
fields = [
|
||||
'id', 'content_type', 'object_id', 'parent', 'name', 'image', 'image_height', 'image_width', 'created',
|
||||
]
|
||||
|
||||
def validate(self, data):
|
||||
|
||||
# Validate that the parent object exists
|
||||
try:
|
||||
data['content_type'].get_object_for_this_type(id=data['object_id'])
|
||||
except ObjectDoesNotExist:
|
||||
raise serializers.ValidationError(
|
||||
"Invalid parent object: {} ID {}".format(data['content_type'], data['object_id'])
|
||||
)
|
||||
|
||||
# Enforce model validation
|
||||
super(ImageAttachmentSerializer, self).validate(data)
|
||||
|
||||
return data
|
||||
|
||||
def get_parent(self, obj):
|
||||
|
||||
@ -102,29 +106,6 @@ class ImageAttachmentSerializer(serializers.ModelSerializer):
|
||||
return serializer(obj.parent, context={'request': self.context['request']}).data
|
||||
|
||||
|
||||
class WritableImageAttachmentSerializer(ValidatedModelSerializer):
|
||||
content_type = ContentTypeFieldSerializer()
|
||||
|
||||
class Meta:
|
||||
model = ImageAttachment
|
||||
fields = ['id', 'content_type', 'object_id', 'name', 'image']
|
||||
|
||||
def validate(self, data):
|
||||
|
||||
# Validate that the parent object exists
|
||||
try:
|
||||
data['content_type'].get_object_for_this_type(id=data['object_id'])
|
||||
except ObjectDoesNotExist:
|
||||
raise serializers.ValidationError(
|
||||
"Invalid parent object: {} ID {}".format(data['content_type'], data['object_id'])
|
||||
)
|
||||
|
||||
# Enforce model validation
|
||||
super(WritableImageAttachmentSerializer, self).validate(data)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
#
|
||||
# Reports
|
||||
#
|
||||
|
@ -67,7 +67,6 @@ class CustomFieldModelViewSet(ModelViewSet):
|
||||
class GraphViewSet(ModelViewSet):
|
||||
queryset = Graph.objects.all()
|
||||
serializer_class = serializers.GraphSerializer
|
||||
write_serializer_class = serializers.WritableGraphSerializer
|
||||
filter_class = filters.GraphFilter
|
||||
|
||||
|
||||
@ -88,7 +87,6 @@ class ExportTemplateViewSet(ModelViewSet):
|
||||
class TopologyMapViewSet(ModelViewSet):
|
||||
queryset = TopologyMap.objects.select_related('site')
|
||||
serializer_class = serializers.TopologyMapSerializer
|
||||
write_serializer_class = serializers.WritableTopologyMapSerializer
|
||||
filter_class = filters.TopologyMapFilter
|
||||
|
||||
@detail_route()
|
||||
@ -118,7 +116,6 @@ class TopologyMapViewSet(ModelViewSet):
|
||||
class ImageAttachmentViewSet(ModelViewSet):
|
||||
queryset = ImageAttachment.objects.all()
|
||||
serializer_class = serializers.ImageAttachmentSerializer
|
||||
write_serializer_class = serializers.WritableImageAttachmentSerializer
|
||||
|
||||
|
||||
#
|
||||
|
@ -4,7 +4,7 @@ from rest_framework import serializers
|
||||
|
||||
from extras.api.customfields import CustomFieldModelSerializer
|
||||
from tenancy.models import Tenant, TenantGroup
|
||||
from utilities.api import ValidatedModelSerializer
|
||||
from utilities.api import ValidatedModelSerializer, WritableNestedSerializer
|
||||
|
||||
|
||||
#
|
||||
@ -18,7 +18,7 @@ class TenantGroupSerializer(ValidatedModelSerializer):
|
||||
fields = ['id', 'name', 'slug']
|
||||
|
||||
|
||||
class NestedTenantGroupSerializer(serializers.ModelSerializer):
|
||||
class NestedTenantGroupSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenantgroup-detail')
|
||||
|
||||
class Meta:
|
||||
@ -31,23 +31,16 @@ class NestedTenantGroupSerializer(serializers.ModelSerializer):
|
||||
#
|
||||
|
||||
class TenantSerializer(CustomFieldModelSerializer):
|
||||
group = NestedTenantGroupSerializer()
|
||||
group = NestedTenantGroupSerializer(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Tenant
|
||||
fields = ['id', 'name', 'slug', 'group', 'description', 'comments', 'custom_fields', 'created', 'last_updated']
|
||||
|
||||
|
||||
class NestedTenantSerializer(serializers.ModelSerializer):
|
||||
class NestedTenantSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenant-detail')
|
||||
|
||||
class Meta:
|
||||
model = Tenant
|
||||
fields = ['id', 'url', 'name', 'slug']
|
||||
|
||||
|
||||
class WritableTenantSerializer(CustomFieldModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Tenant
|
||||
fields = ['id', 'name', 'slug', 'group', 'description', 'comments', 'custom_fields', 'created', 'last_updated']
|
||||
|
@ -32,5 +32,4 @@ class TenantGroupViewSet(ModelViewSet):
|
||||
class TenantViewSet(CustomFieldModelViewSet):
|
||||
queryset = Tenant.objects.select_related('group')
|
||||
serializer_class = serializers.TenantSerializer
|
||||
write_serializer_class = serializers.WritableTenantSerializer
|
||||
filter_class = filters.TenantFilter
|
||||
|
@ -1,10 +1,11 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import serializers
|
||||
|
||||
from utilities.api import WritableNestedSerializer
|
||||
|
||||
|
||||
class NestedUserSerializer(serializers.ModelSerializer):
|
||||
class NestedUserSerializer(WritableNestedSerializer):
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
|
Loading…
Reference in New Issue
Block a user