Pull in Serializers for Vapor overrides

* Avoids modifications with upstream methods
 * Overrides VLAN, Interface, and ConnectedEndpoint serializers for Vapor specific needs
This commit is contained in:
Marco Ceppi 2019-12-15 07:09:16 -05:00
parent 4b23149dff
commit 9fa125f1a4

View File

@ -1,24 +1,112 @@
from rest_framework import serializers
from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField
from drf_yasg.utils import swagger_serializer_method
from dcim.constants import CONNECTION_STATUS_CHOICES, IFACE_TYPE_CHOICES
from extras.api.customfields import CustomFieldModelSerializer
from dcim.api.nested_serializers import (
NestedDeviceSerializer,
NestedInterfaceSerializer,
NestedCableSerializer,
)
from dcim.api.serializers import (
InterfaceConnectionSerializer,
ConnectedEndpointSerializer,
IFACE_TYPE_CHOICES,
IFACE_MODE_CHOICES,
)
from dcim.models import Interface
from ipam.api.nested_serializers import NestedVLANSerializer
from ipam.models import VLAN
from ipam.api.nested_serializers import NestedPrefixSerializer
from ipam.models import VLAN, Prefix
from tenancy.api.nested_serializers import NestedTenantGroupSerializer
from utilities.api import ChoiceField, ValidatedModelSerializer, SerializedPKRelatedField
from utilities.api import ChoiceField, ValidatedModelSerializer, SerializedPKRelatedField, WritableNestedSerializer
from tenancy.models import Tenant as Customer
from utilities.utils import dynamic_import
def get_serializer_for_model(model, prefix=''):
"""
Dynamically resolve and return the appropriate serializer for a model.
"""
app_name, model_name = model._meta.label.split('.')
serializer_name = '{}.api.serializers.{}{}Serializer'.format(
app_name, prefix, model_name
)
override_serializer_name = 'vapor.api.serializers.{}{}Serializer'.format(
prefix, model_name
)
try:
return dynamic_import(override_serializer_name)
except AttributeError:
pass
try:
return dynamic_import(serializer_name)
except AttributeError:
raise SerializerNotFound(
"Could not determine serializer for {}.{} with prefix '{}'".format(app_name, model_name, prefix)
)
class NestedVLANSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
prefixes = SerializedPKRelatedField(
queryset=Prefix.objects.all(),
serializer=NestedPrefixSerializer,
required=False,
many=True,
)
class Meta:
model = VLAN
fields = ['id', 'url', 'vid', 'name', 'display_name', 'prefixes']
class NestedInterfaceSerializer(WritableNestedSerializer):
device = NestedDeviceSerializer(read_only=True)
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
connection_status = ChoiceField(choices=CONNECTION_STATUS_CHOICES, read_only=True)
type = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False)
untagged_vlan = NestedVLANSerializer(required=False, allow_null=True)
tagged_vlans = SerializedPKRelatedField(
queryset=VLAN.objects.all(),
serializer=NestedVLANSerializer,
required=False,
many=True,
)
class Meta:
model = Interface
fields = ['id', 'url', 'device', 'name', 'cable', 'connection_status', 'type', 'untagged_vlan', 'tagged_vlans']
class ConnectedEndpointSerializer(ValidatedModelSerializer):
connected_endpoint_type = serializers.SerializerMethodField(read_only=True)
connected_endpoint = serializers.SerializerMethodField(read_only=True)
connection_status = ChoiceField(choices=CONNECTION_STATUS_CHOICES, read_only=True)
def get_connected_endpoint_type(self, obj):
if hasattr(obj, 'connected_endpoint') and obj.connected_endpoint is not None:
return '{}.{}'.format(
obj.connected_endpoint._meta.app_label,
obj.connected_endpoint._meta.model_name
)
return None
@swagger_serializer_method(serializer_or_field=serializers.DictField)
def get_connected_endpoint(self, obj):
"""
Return the appropriate serializer for the type of connected object.
"""
if getattr(obj, 'connected_endpoint', None) is None:
return None
serializer = get_serializer_for_model(obj.connected_endpoint, prefix='Nested')
context = {'request': self.context['request']}
data = serializer(obj.connected_endpoint, context=context).data
return data
class CustomerSerializer(TaggitSerializer, CustomFieldModelSerializer):