Introduced WritableSerializerMixin

This commit is contained in:
Jeremy Stretch 2017-01-27 14:36:13 -05:00
parent fa900d5dbb
commit 12d263999b
6 changed files with 68 additions and 37 deletions

View File

@ -9,6 +9,7 @@ from circuits.models import Provider, CircuitTermination, CircuitType, Circuit
from circuits.filters import CircuitFilter from circuits.filters import CircuitFilter
from extras.api.views import CustomFieldModelViewSet from extras.api.views import CustomFieldModelViewSet
from utilities.api import WritableSerializerMixin
from . import serializers from . import serializers
@ -34,26 +35,23 @@ class CircuitTypeViewSet(ModelViewSet):
# Circuits # Circuits
# #
class CircuitViewSet(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
filter_class = CircuitFilter filter_class = CircuitFilter
def get_serializer_class(self):
if self.action == 'retrieve':
return serializers.CircuitDetailSerializer
return serializers.CircuitSerializer
# #
# Circuit Terminations # Circuit Terminations
# #
class CircuitTerminationViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): class CircuitTerminationViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin,
GenericViewSet):
queryset = CircuitTermination.objects.select_related('site', 'interface__device') queryset = CircuitTermination.objects.select_related('site', 'interface__device')
serializer_class = serializers.CircuitTerminationSerializer serializer_class = serializers.CircuitTerminationSerializer
class NestedCircuitTerminationViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): class NestedCircuitTerminationViewSet(CreateModelMixin, ListModelMixin ,WritableSerializerMixin, GenericViewSet):
serializer_class = serializers.CircuitTerminationSerializer serializer_class = serializers.CircuitTerminationSerializer
def get_queryset(self): def get_queryset(self):

View File

@ -18,7 +18,7 @@ from dcim.models import (
from dcim import filters from dcim import filters
from extras.api.views import CustomFieldModelViewSet from extras.api.views import CustomFieldModelViewSet
from extras.api.renderers import BINDZoneRenderer, FlatJSONRenderer from extras.api.renderers import BINDZoneRenderer, FlatJSONRenderer
from utilities.api import ServiceUnavailable from utilities.api import ServiceUnavailable, WritableSerializerMixin
from .exceptions import MissingFilterException from .exceptions import MissingFilterException
from . import serializers from . import serializers
@ -27,7 +27,7 @@ from . import serializers
# Sites # Sites
# #
class SiteViewSet(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
@ -36,7 +36,7 @@ class SiteViewSet(CustomFieldModelViewSet):
# Rack groups # Rack groups
# #
class RackGroupViewSet(ModelViewSet): 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
@ -55,7 +55,7 @@ class RackRoleViewSet(ModelViewSet):
# Racks # Racks
# #
class RackViewSet(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
filter_class = filters.RackFilter filter_class = filters.RackFilter
@ -102,7 +102,7 @@ class ManufacturerViewSet(ModelViewSet):
# Device Types # Device Types
# #
class DeviceTypeViewSet(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
@ -129,7 +129,7 @@ class PlatformViewSet(ModelViewSet):
# Devices # Devices
# #
class DeviceViewSet(CustomFieldModelViewSet): class DeviceViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Device.objects.select_related( queryset = Device.objects.select_related(
'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'rack__site', 'parent_bay', 'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'rack__site', 'parent_bay',
).prefetch_related( ).prefetch_related(
@ -144,12 +144,13 @@ class DeviceViewSet(CustomFieldModelViewSet):
# Console Ports # Console Ports
# #
class ConsolePortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): class ConsolePortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin,
GenericViewSet):
queryset = ConsolePort.objects.select_related('cs_port') queryset = ConsolePort.objects.select_related('cs_port')
serializer_class = serializers.ConsolePortSerializer serializer_class = serializers.ConsolePortSerializer
class ChildConsolePortViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): class ChildConsolePortViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet):
serializer_class = serializers.ChildConsoleServerPortSerializer serializer_class = serializers.ChildConsoleServerPortSerializer
def get_queryset(self): def get_queryset(self):
@ -161,12 +162,13 @@ class ChildConsolePortViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
# Console Server Ports # Console Server Ports
# #
class ConsoleServerPortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): class ConsoleServerPortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin,
GenericViewSet):
queryset = ConsoleServerPort.objects.select_related('connected_console') queryset = ConsoleServerPort.objects.select_related('connected_console')
serializer_class = serializers.ConsoleServerPortSerializer serializer_class = serializers.ConsoleServerPortSerializer
class ChildConsoleServerPortViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): class ChildConsoleServerPortViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet):
serializer_class = serializers.ChildConsoleServerPortSerializer serializer_class = serializers.ChildConsoleServerPortSerializer
def get_queryset(self): def get_queryset(self):
@ -178,12 +180,13 @@ class ChildConsoleServerPortViewSet(CreateModelMixin, ListModelMixin, GenericVie
# Power Ports # Power Ports
# #
class PowerPortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): class PowerPortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin,
GenericViewSet):
queryset = PowerPort.objects.select_related('power_outlet') queryset = PowerPort.objects.select_related('power_outlet')
serializer_class = serializers.PowerPortSerializer serializer_class = serializers.PowerPortSerializer
class NestedPowerPortViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): class NestedPowerPortViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet):
serializer_class = serializers.ChildPowerPortSerializer serializer_class = serializers.ChildPowerPortSerializer
def get_queryset(self): def get_queryset(self):
@ -195,12 +198,13 @@ class NestedPowerPortViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
# Power Outlets # Power Outlets
# #
class PowerOutletViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): class PowerOutletViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin,
GenericViewSet):
queryset = PowerOutlet.objects.select_related('connected_port') queryset = PowerOutlet.objects.select_related('connected_port')
serializer_class = serializers.PowerOutletSerializer serializer_class = serializers.PowerOutletSerializer
class NestedPowerOutletViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): class NestedPowerOutletViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet):
serializer_class = serializers.ChildPowerOutletSerializer serializer_class = serializers.ChildPowerOutletSerializer
def get_queryset(self): def get_queryset(self):
@ -212,12 +216,13 @@ class NestedPowerOutletViewSet(CreateModelMixin, ListModelMixin, GenericViewSet)
# Interfaces # Interfaces
# #
class InterfaceViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): class InterfaceViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin,
GenericViewSet):
queryset = Interface.objects.select_related('device') queryset = Interface.objects.select_related('device')
serializer_class = serializers.InterfaceDetailSerializer serializer_class = serializers.InterfaceDetailSerializer
class NestedInterfaceViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): class NestedInterfaceViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet):
serializer_class = serializers.ChildInterfaceSerializer serializer_class = serializers.ChildInterfaceSerializer
filter_class = filters.InterfaceFilter filter_class = filters.InterfaceFilter
@ -231,12 +236,13 @@ class NestedInterfaceViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
# Device bays # Device bays
# #
class DeviceBayViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): class DeviceBayViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin,
GenericViewSet):
queryset = DeviceBay.objects.select_related('installed_device') queryset = DeviceBay.objects.select_related('installed_device')
serializer_class = serializers.DeviceBaySerializer serializer_class = serializers.DeviceBaySerializer
class NestedDeviceBayViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): class NestedDeviceBayViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet):
serializer_class = serializers.ChildDeviceBaySerializer serializer_class = serializers.ChildDeviceBaySerializer
def get_queryset(self): def get_queryset(self):
@ -248,12 +254,12 @@ class NestedDeviceBayViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
# Modules # Modules
# #
class ModuleViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): class ModuleViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin, GenericViewSet):
queryset = Module.objects.select_related('device', 'manufacturer') queryset = Module.objects.select_related('device', 'manufacturer')
serializer_class = serializers.ModuleSerializer serializer_class = serializers.ModuleSerializer
class NestedModuleViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): class NestedModuleViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet):
serializer_class = serializers.ChildModuleSerializer serializer_class = serializers.ChildModuleSerializer
def get_queryset(self): def get_queryset(self):

View File

@ -4,6 +4,7 @@ from dcim.api.serializers import NestedDeviceSerializer, ChildInterfaceSerialize
from extras.api.serializers import CustomFieldSerializer from extras.api.serializers import CustomFieldSerializer
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
# #
@ -84,7 +85,7 @@ class NestedAggregateSerializer(serializers.HyperlinkedModelSerializer):
# VLAN groups # VLAN groups
# #
class VLANGroupSerializer(serializers.ModelSerializer): class VLANGroupSerializer(WritableSerializerMixin, serializers.ModelSerializer):
site = NestedSiteSerializer() site = NestedSiteSerializer()
class Meta: class Meta:

View File

@ -4,6 +4,7 @@ from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN,
from ipam import filters from ipam import filters
from extras.api.views import CustomFieldModelViewSet from extras.api.views import CustomFieldModelViewSet
from utilities.api import WritableSerializerMixin
from . import serializers from . import serializers
@ -11,7 +12,7 @@ from . import serializers
# VRFs # VRFs
# #
class VRFViewSet(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
filter_class = filters.VRFFilter filter_class = filters.VRFFilter
@ -39,7 +40,7 @@ class RIRViewSet(ModelViewSet):
# Aggregates # Aggregates
# #
class AggregateViewSet(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
filter_class = filters.AggregateFilter filter_class = filters.AggregateFilter
@ -49,7 +50,7 @@ class AggregateViewSet(CustomFieldModelViewSet):
# Prefixes # Prefixes
# #
class PrefixViewSet(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
filter_class = filters.PrefixFilter filter_class = filters.PrefixFilter
@ -59,7 +60,7 @@ class PrefixViewSet(CustomFieldModelViewSet):
# IP addresses # IP addresses
# #
class IPAddressViewSet(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
filter_class = filters.IPAddressFilter filter_class = filters.IPAddressFilter
@ -69,7 +70,7 @@ class IPAddressViewSet(CustomFieldModelViewSet):
# VLAN groups # VLAN groups
# #
class VLANGroupViewSet(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
filter_class = filters.VLANGroupFilter filter_class = filters.VLANGroupFilter
@ -79,7 +80,7 @@ class VLANGroupViewSet(ModelViewSet):
# VLANs # VLANs
# #
class VLANViewSet(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
filter_class = filters.VLANFilter filter_class = filters.VLANFilter
@ -89,7 +90,7 @@ class VLANViewSet(CustomFieldModelViewSet):
# Services # Services
# #
class ServiceViewSet(ModelViewSet): class ServiceViewSet(WritableSerializerMixin, ModelViewSet):
queryset = Service.objects.select_related('device').prefetch_related('ipaddresses') queryset = Service.objects.select_related('device').prefetch_related('ipaddresses')
serializer_class = serializers.ServiceSerializer serializer_class = serializers.ServiceSerializer
filter_class = filters.ServiceFilter filter_class = filters.ServiceFilter

View File

@ -4,6 +4,7 @@ from tenancy.models import Tenant, TenantGroup
from tenancy.filters import TenantFilter from tenancy.filters import TenantFilter
from extras.api.views import CustomFieldModelViewSet from extras.api.views import CustomFieldModelViewSet
from utilities.api import WritableSerializerMixin
from . import serializers from . import serializers
@ -20,7 +21,7 @@ class TenantGroupViewSet(ModelViewSet):
# Tenants # Tenants
# #
class TenantViewSet(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
filter_class = TenantFilter filter_class = TenantFilter

View File

@ -1,6 +1,30 @@
from rest_framework.exceptions import APIException from rest_framework.exceptions import APIException
from rest_framework.serializers import ModelSerializer
WRITE_OPERATIONS = ['create', 'update', 'partial_update', 'delete']
class ServiceUnavailable(APIException): class ServiceUnavailable(APIException):
status_code = 503 status_code = 503
default_detail = "Service temporarily unavailable, please try again later." default_detail = "Service temporarily unavailable, please try again later."
class WritableSerializerMixin(object):
"""
Returns a flat Serializer from the given model suitable for write operations (POST, PUT, PATCH). This is necessary
to allow write operations on objects which utilize nested serializers.
"""
def get_serializer_class(self):
class WritableSerializer(ModelSerializer):
class Meta:
model = self.queryset.model
fields = '__all__'
if self.action in WRITE_OPERATIONS:
return WritableSerializer
return self.serializer_class