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

View File

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

View File

@ -4,6 +4,7 @@ from dcim.api.serializers import NestedDeviceSerializer, ChildInterfaceSerialize
from extras.api.serializers import CustomFieldSerializer
from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
from tenancy.api.serializers import NestedTenantSerializer
from utilities.api import WritableSerializerMixin
#
@ -84,7 +85,7 @@ class NestedAggregateSerializer(serializers.HyperlinkedModelSerializer):
# VLAN groups
#
class VLANGroupSerializer(serializers.ModelSerializer):
class VLANGroupSerializer(WritableSerializerMixin, serializers.ModelSerializer):
site = NestedSiteSerializer()
class Meta:

View File

@ -4,6 +4,7 @@ from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN,
from ipam import filters
from extras.api.views import CustomFieldModelViewSet
from utilities.api import WritableSerializerMixin
from . import serializers
@ -11,7 +12,7 @@ from . import serializers
# VRFs
#
class VRFViewSet(CustomFieldModelViewSet):
class VRFViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = VRF.objects.select_related('tenant')
serializer_class = serializers.VRFSerializer
filter_class = filters.VRFFilter
@ -39,7 +40,7 @@ class RIRViewSet(ModelViewSet):
# Aggregates
#
class AggregateViewSet(CustomFieldModelViewSet):
class AggregateViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Aggregate.objects.select_related('rir')
serializer_class = serializers.AggregateSerializer
filter_class = filters.AggregateFilter
@ -49,7 +50,7 @@ class AggregateViewSet(CustomFieldModelViewSet):
# Prefixes
#
class PrefixViewSet(CustomFieldModelViewSet):
class PrefixViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Prefix.objects.select_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
serializer_class = serializers.PrefixSerializer
filter_class = filters.PrefixFilter
@ -59,7 +60,7 @@ class PrefixViewSet(CustomFieldModelViewSet):
# IP addresses
#
class IPAddressViewSet(CustomFieldModelViewSet):
class IPAddressViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant', 'interface__device', 'nat_inside')
serializer_class = serializers.IPAddressSerializer
filter_class = filters.IPAddressFilter
@ -69,7 +70,7 @@ class IPAddressViewSet(CustomFieldModelViewSet):
# VLAN groups
#
class VLANGroupViewSet(ModelViewSet):
class VLANGroupViewSet(WritableSerializerMixin, ModelViewSet):
queryset = VLANGroup.objects.select_related('site')
serializer_class = serializers.VLANGroupSerializer
filter_class = filters.VLANGroupFilter
@ -79,7 +80,7 @@ class VLANGroupViewSet(ModelViewSet):
# VLANs
#
class VLANViewSet(CustomFieldModelViewSet):
class VLANViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = VLAN.objects.select_related('site', 'group', 'tenant', 'role')
serializer_class = serializers.VLANSerializer
filter_class = filters.VLANFilter
@ -89,7 +90,7 @@ class VLANViewSet(CustomFieldModelViewSet):
# Services
#
class ServiceViewSet(ModelViewSet):
class ServiceViewSet(WritableSerializerMixin, ModelViewSet):
queryset = Service.objects.select_related('device').prefetch_related('ipaddresses')
serializer_class = serializers.ServiceSerializer
filter_class = filters.ServiceFilter

View File

@ -4,6 +4,7 @@ from tenancy.models import Tenant, TenantGroup
from tenancy.filters import TenantFilter
from extras.api.views import CustomFieldModelViewSet
from utilities.api import WritableSerializerMixin
from . import serializers
@ -20,7 +21,7 @@ class TenantGroupViewSet(ModelViewSet):
# Tenants
#
class TenantViewSet(CustomFieldModelViewSet):
class TenantViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = Tenant.objects.select_related('group')
serializer_class = serializers.TenantSerializer
filter_class = TenantFilter

View File

@ -1,6 +1,30 @@
from rest_framework.exceptions import APIException
from rest_framework.serializers import ModelSerializer
WRITE_OPERATIONS = ['create', 'update', 'partial_update', 'delete']
class ServiceUnavailable(APIException):
status_code = 503
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