diff --git a/netbox/circuits/api/serializers.py b/netbox/circuits/api/serializers.py index 6bac48a59..e8171e2fb 100644 --- a/netbox/circuits/api/serializers.py +++ b/netbox/circuits/api/serializers.py @@ -1,11 +1,11 @@ from rest_framework import serializers -from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from circuits.choices import CircuitStatusChoices from circuits.models import Provider, Circuit, CircuitTermination, CircuitType from dcim.api.nested_serializers import NestedCableSerializer, NestedInterfaceSerializer, NestedSiteSerializer from dcim.api.serializers import ConnectedEndpointSerializer from extras.api.customfields import CustomFieldModelSerializer +from extras.api.serializers import TaggedObjectSerializer from tenancy.api.nested_serializers import NestedTenantSerializer from utilities.api import ChoiceField, ValidatedModelSerializer, WritableNestedSerializer from .nested_serializers import * @@ -15,8 +15,7 @@ from .nested_serializers import * # Providers # -class ProviderSerializer(TaggitSerializer, CustomFieldModelSerializer): - tags = TagListSerializerField(required=False) +class ProviderSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): circuit_count = serializers.IntegerField(read_only=True) class Meta: @@ -49,14 +48,13 @@ class CircuitCircuitTerminationSerializer(WritableNestedSerializer): fields = ['id', 'url', 'site', 'connected_endpoint', 'port_speed', 'upstream_speed', 'xconnect_id'] -class CircuitSerializer(TaggitSerializer, CustomFieldModelSerializer): +class CircuitSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): provider = NestedProviderSerializer() status = ChoiceField(choices=CircuitStatusChoices, required=False) type = NestedCircuitTypeSerializer() tenant = NestedTenantSerializer(required=False, allow_null=True) termination_a = CircuitCircuitTerminationSerializer(read_only=True) termination_z = CircuitCircuitTerminationSerializer(read_only=True) - tags = TagListSerializerField(required=False) class Meta: model = Circuit diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 5250045c5..c684b8041 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -2,7 +2,6 @@ from django.contrib.contenttypes.models import ContentType from drf_yasg.utils import swagger_serializer_method from rest_framework import serializers from rest_framework.validators import UniqueTogetherValidator -from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from dcim.choices import * from dcim.constants import * @@ -14,6 +13,7 @@ from dcim.models import ( VirtualChassis, ) from extras.api.customfields import CustomFieldModelSerializer +from extras.api.serializers import TaggedObjectSerializer from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer from ipam.models import VLAN from tenancy.api.nested_serializers import NestedTenantSerializer @@ -67,12 +67,11 @@ class RegionSerializer(serializers.ModelSerializer): fields = ['id', 'name', 'slug', 'parent', 'description', 'site_count'] -class SiteSerializer(TaggitSerializer, CustomFieldModelSerializer): +class SiteSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): status = ChoiceField(choices=SiteStatusChoices, required=False) region = NestedRegionSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True) time_zone = TimeZoneField(required=False) - tags = TagListSerializerField(required=False) circuit_count = serializers.IntegerField(read_only=True) device_count = serializers.IntegerField(read_only=True) prefix_count = serializers.IntegerField(read_only=True) @@ -112,7 +111,7 @@ class RackRoleSerializer(ValidatedModelSerializer): fields = ['id', 'name', 'slug', 'color', 'description', 'rack_count'] -class RackSerializer(TaggitSerializer, CustomFieldModelSerializer): +class RackSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): site = NestedSiteSerializer() group = NestedRackGroupSerializer(required=False, allow_null=True, default=None) tenant = NestedTenantSerializer(required=False, allow_null=True) @@ -121,7 +120,6 @@ class RackSerializer(TaggitSerializer, CustomFieldModelSerializer): type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False) width = ChoiceField(choices=RackWidthChoices, required=False) outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False) - tags = TagListSerializerField(required=False) device_count = serializers.IntegerField(read_only=True) powerfeed_count = serializers.IntegerField(read_only=True) @@ -161,11 +159,10 @@ class RackUnitSerializer(serializers.Serializer): device = NestedDeviceSerializer(read_only=True) -class RackReservationSerializer(ValidatedModelSerializer): +class RackReservationSerializer(TaggedObjectSerializer, ValidatedModelSerializer): rack = NestedRackSerializer() user = NestedUserSerializer() tenant = NestedTenantSerializer(required=False, allow_null=True) - tags = TagListSerializerField(required=False) class Meta: model = RackReservation @@ -224,10 +221,9 @@ class ManufacturerSerializer(ValidatedModelSerializer): ] -class DeviceTypeSerializer(TaggitSerializer, CustomFieldModelSerializer): +class DeviceTypeSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): manufacturer = NestedManufacturerSerializer() subdevice_role = ChoiceField(choices=SubdeviceRoleChoices, allow_blank=True, required=False) - tags = TagListSerializerField(required=False) device_count = serializers.IntegerField(read_only=True) class Meta: @@ -363,7 +359,7 @@ class PlatformSerializer(ValidatedModelSerializer): ] -class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer): +class DeviceSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): device_type = NestedDeviceTypeSerializer() device_role = NestedDeviceRoleSerializer() tenant = NestedTenantSerializer(required=False, allow_null=True) @@ -378,7 +374,6 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer): parent_device = serializers.SerializerMethodField() cluster = NestedClusterSerializer(required=False, allow_null=True) virtual_chassis = NestedVirtualChassisSerializer(required=False, allow_null=True) - tags = TagListSerializerField(required=False) class Meta: model = Device @@ -434,7 +429,7 @@ class DeviceNAPALMSerializer(serializers.Serializer): method = serializers.DictField() -class ConsoleServerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer): +class ConsoleServerPortSerializer(TaggedObjectSerializer, ConnectedEndpointSerializer): device = NestedDeviceSerializer() type = ChoiceField( choices=ConsolePortTypeChoices, @@ -442,7 +437,6 @@ class ConsoleServerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer) required=False ) cable = NestedCableSerializer(read_only=True) - tags = TagListSerializerField(required=False) class Meta: model = ConsoleServerPort @@ -452,7 +446,7 @@ class ConsoleServerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer) ] -class ConsolePortSerializer(TaggitSerializer, ConnectedEndpointSerializer): +class ConsolePortSerializer(TaggedObjectSerializer, ConnectedEndpointSerializer): device = NestedDeviceSerializer() type = ChoiceField( choices=ConsolePortTypeChoices, @@ -460,7 +454,6 @@ class ConsolePortSerializer(TaggitSerializer, ConnectedEndpointSerializer): required=False ) cable = NestedCableSerializer(read_only=True) - tags = TagListSerializerField(required=False) class Meta: model = ConsolePort @@ -470,7 +463,7 @@ class ConsolePortSerializer(TaggitSerializer, ConnectedEndpointSerializer): ] -class PowerOutletSerializer(TaggitSerializer, ConnectedEndpointSerializer): +class PowerOutletSerializer(TaggedObjectSerializer, ConnectedEndpointSerializer): device = NestedDeviceSerializer() type = ChoiceField( choices=PowerOutletTypeChoices, @@ -488,9 +481,6 @@ class PowerOutletSerializer(TaggitSerializer, ConnectedEndpointSerializer): cable = NestedCableSerializer( read_only=True ) - tags = TagListSerializerField( - required=False - ) class Meta: model = PowerOutlet @@ -500,7 +490,7 @@ class PowerOutletSerializer(TaggitSerializer, ConnectedEndpointSerializer): ] -class PowerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer): +class PowerPortSerializer(TaggedObjectSerializer, ConnectedEndpointSerializer): device = NestedDeviceSerializer() type = ChoiceField( choices=PowerPortTypeChoices, @@ -508,7 +498,6 @@ class PowerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer): required=False ) cable = NestedCableSerializer(read_only=True) - tags = TagListSerializerField(required=False) class Meta: model = PowerPort @@ -518,7 +507,7 @@ class PowerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer): ] -class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer): +class InterfaceSerializer(TaggedObjectSerializer, ConnectedEndpointSerializer): device = NestedDeviceSerializer() type = ChoiceField(choices=InterfaceTypeChoices) lag = NestedInterfaceSerializer(required=False, allow_null=True) @@ -531,7 +520,6 @@ class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer): many=True ) cable = NestedCableSerializer(read_only=True) - tags = TagListSerializerField(required=False) count_ipaddresses = serializers.IntegerField(read_only=True) class Meta: @@ -563,11 +551,10 @@ class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer): return super().validate(data) -class RearPortSerializer(TaggitSerializer, ValidatedModelSerializer): +class RearPortSerializer(TaggedObjectSerializer, ValidatedModelSerializer): device = NestedDeviceSerializer() type = ChoiceField(choices=PortTypeChoices) cable = NestedCableSerializer(read_only=True) - tags = TagListSerializerField(required=False) class Meta: model = RearPort @@ -585,22 +572,20 @@ class FrontPortRearPortSerializer(WritableNestedSerializer): fields = ['id', 'url', 'name'] -class FrontPortSerializer(TaggitSerializer, ValidatedModelSerializer): +class FrontPortSerializer(TaggedObjectSerializer, ValidatedModelSerializer): device = NestedDeviceSerializer() type = ChoiceField(choices=PortTypeChoices) rear_port = FrontPortRearPortSerializer() cable = NestedCableSerializer(read_only=True) - tags = TagListSerializerField(required=False) class Meta: model = FrontPort fields = ['id', 'device', 'name', 'type', 'rear_port', 'rear_port_position', 'description', 'cable', 'tags'] -class DeviceBaySerializer(TaggitSerializer, ValidatedModelSerializer): +class DeviceBaySerializer(TaggedObjectSerializer, ValidatedModelSerializer): device = NestedDeviceSerializer() installed_device = NestedDeviceSerializer(required=False, allow_null=True) - tags = TagListSerializerField(required=False) class Meta: model = DeviceBay @@ -611,12 +596,11 @@ class DeviceBaySerializer(TaggitSerializer, ValidatedModelSerializer): # Inventory items # -class InventoryItemSerializer(TaggitSerializer, ValidatedModelSerializer): +class InventoryItemSerializer(TaggedObjectSerializer, ValidatedModelSerializer): device = NestedDeviceSerializer() # Provide a default value to satisfy UniqueTogetherValidator parent = serializers.PrimaryKeyRelatedField(queryset=InventoryItem.objects.all(), allow_null=True, default=None) manufacturer = NestedManufacturerSerializer(required=False, allow_null=True, default=None) - tags = TagListSerializerField(required=False) class Meta: model = InventoryItem @@ -630,7 +614,7 @@ class InventoryItemSerializer(TaggitSerializer, ValidatedModelSerializer): # Cables # -class CableSerializer(ValidatedModelSerializer): +class CableSerializer(TaggedObjectSerializer, ValidatedModelSerializer): termination_a_type = ContentTypeField( queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS) ) @@ -641,7 +625,6 @@ class CableSerializer(ValidatedModelSerializer): termination_b = serializers.SerializerMethodField(read_only=True) status = ChoiceField(choices=CableStatusChoices, required=False) length_unit = ChoiceField(choices=CableLengthUnitChoices, allow_blank=True, required=False) - tags = TagListSerializerField(required=False) class Meta: model = Cable @@ -710,9 +693,8 @@ class InterfaceConnectionSerializer(ValidatedModelSerializer): # Virtual chassis # -class VirtualChassisSerializer(TaggitSerializer, ValidatedModelSerializer): +class VirtualChassisSerializer(TaggedObjectSerializer, ValidatedModelSerializer): master = NestedDeviceSerializer() - tags = TagListSerializerField(required=False) member_count = serializers.IntegerField(read_only=True) class Meta: @@ -724,14 +706,13 @@ class VirtualChassisSerializer(TaggitSerializer, ValidatedModelSerializer): # Power panels # -class PowerPanelSerializer(ValidatedModelSerializer): +class PowerPanelSerializer(TaggedObjectSerializer, ValidatedModelSerializer): site = NestedSiteSerializer() rack_group = NestedRackGroupSerializer( required=False, allow_null=True, default=None ) - tags = TagListSerializerField(required=False) powerfeed_count = serializers.IntegerField(read_only=True) class Meta: @@ -739,7 +720,7 @@ class PowerPanelSerializer(ValidatedModelSerializer): fields = ['id', 'site', 'rack_group', 'name', 'tags', 'powerfeed_count'] -class PowerFeedSerializer(TaggitSerializer, CustomFieldModelSerializer): +class PowerFeedSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): power_panel = NestedPowerPanelSerializer() rack = NestedRackSerializer( required=False, @@ -762,9 +743,6 @@ class PowerFeedSerializer(TaggitSerializer, CustomFieldModelSerializer): choices=PowerFeedPhaseChoices, default=PowerFeedPhaseChoices.PHASE_SINGLE ) - tags = TagListSerializerField( - required=False - ) class Meta: model = PowerFeed diff --git a/netbox/extras/api/nested_serializers.py b/netbox/extras/api/nested_serializers.py index 672b10a78..4e95b389b 100644 --- a/netbox/extras/api/nested_serializers.py +++ b/netbox/extras/api/nested_serializers.py @@ -38,11 +38,10 @@ class NestedGraphSerializer(WritableNestedSerializer): class NestedTagSerializer(WritableNestedSerializer): url = serializers.HyperlinkedIdentityField(view_name='extras-api:tag-detail') - tagged_items = serializers.IntegerField(read_only=True) class Meta: model = models.Tag - fields = ['id', 'url', 'name', 'slug', 'color', 'tagged_items'] + fields = ['id', 'url', 'name', 'slug', 'color'] class NestedReportResultSerializer(serializers.ModelSerializer): diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index 54c0650da..5bf664b2f 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -95,6 +95,28 @@ class TagSerializer(ValidatedModelSerializer): fields = ['id', 'name', 'slug', 'color', 'description', 'tagged_items'] +class TaggedObjectSerializer(serializers.Serializer): + tags = NestedTagSerializer(many=True, required=False) + + def create(self, validated_data): + tags = validated_data.pop('tags', []) + instance = super().create(validated_data) + + return self._save_tags(instance, tags) + + def update(self, instance, validated_data): + tags = validated_data.pop('tags', []) + instance = super().update(instance, validated_data) + + return self._save_tags(instance, tags) + + def _save_tags(self, instance, tags): + if tags: + instance.tags.set(*[t.name for t in tags]) + + return instance + + # # Image attachments # diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index f5de2f509..e92006096 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -3,11 +3,11 @@ from collections import OrderedDict from rest_framework import serializers from rest_framework.reverse import reverse from rest_framework.validators import UniqueTogetherValidator -from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from dcim.api.nested_serializers import NestedDeviceSerializer, NestedSiteSerializer from dcim.models import Interface from extras.api.customfields import CustomFieldModelSerializer +from extras.api.serializers import TaggedObjectSerializer from ipam.choices import * from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF from tenancy.api.nested_serializers import NestedTenantSerializer @@ -22,9 +22,8 @@ from .nested_serializers import * # VRFs # -class VRFSerializer(TaggitSerializer, CustomFieldModelSerializer): +class VRFSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): tenant = NestedTenantSerializer(required=False, allow_null=True) - tags = TagListSerializerField(required=False) ipaddress_count = serializers.IntegerField(read_only=True) prefix_count = serializers.IntegerField(read_only=True) @@ -48,10 +47,9 @@ class RIRSerializer(ValidatedModelSerializer): fields = ['id', 'name', 'slug', 'is_private', 'description', 'aggregate_count'] -class AggregateSerializer(TaggitSerializer, CustomFieldModelSerializer): +class AggregateSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True) rir = NestedRIRSerializer() - tags = TagListSerializerField(required=False) class Meta: model = Aggregate @@ -98,13 +96,12 @@ class VLANGroupSerializer(ValidatedModelSerializer): return data -class VLANSerializer(TaggitSerializer, CustomFieldModelSerializer): +class VLANSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): site = NestedSiteSerializer(required=False, allow_null=True) group = NestedVLANGroupSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True) status = ChoiceField(choices=VLANStatusChoices, required=False) role = NestedRoleSerializer(required=False, allow_null=True) - tags = TagListSerializerField(required=False) prefix_count = serializers.IntegerField(read_only=True) class Meta: @@ -133,7 +130,7 @@ class VLANSerializer(TaggitSerializer, CustomFieldModelSerializer): # Prefixes # -class PrefixSerializer(TaggitSerializer, CustomFieldModelSerializer): +class PrefixSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True) site = NestedSiteSerializer(required=False, allow_null=True) vrf = NestedVRFSerializer(required=False, allow_null=True) @@ -141,7 +138,6 @@ class PrefixSerializer(TaggitSerializer, CustomFieldModelSerializer): vlan = NestedVLANSerializer(required=False, allow_null=True) status = ChoiceField(choices=PrefixStatusChoices, required=False) role = NestedRoleSerializer(required=False, allow_null=True) - tags = TagListSerializerField(required=False) class Meta: model = Prefix @@ -226,7 +222,7 @@ class IPAddressInterfaceSerializer(WritableNestedSerializer): return reverse(url_name, kwargs={'pk': obj.pk}, request=self.context['request']) -class IPAddressSerializer(TaggitSerializer, CustomFieldModelSerializer): +class IPAddressSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True) vrf = NestedVRFSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True) @@ -235,7 +231,6 @@ class IPAddressSerializer(TaggitSerializer, CustomFieldModelSerializer): interface = IPAddressInterfaceSerializer(required=False, allow_null=True) nat_inside = NestedIPAddressSerializer(required=False, allow_null=True) nat_outside = NestedIPAddressSerializer(read_only=True) - tags = TagListSerializerField(required=False) class Meta: model = IPAddress @@ -270,7 +265,7 @@ class AvailableIPSerializer(serializers.Serializer): # Services # -class ServiceSerializer(TaggitSerializer, CustomFieldModelSerializer): +class ServiceSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): device = NestedDeviceSerializer(required=False, allow_null=True) virtual_machine = NestedVirtualMachineSerializer(required=False, allow_null=True) protocol = ChoiceField(choices=ServiceProtocolChoices, required=False) @@ -280,7 +275,6 @@ class ServiceSerializer(TaggitSerializer, CustomFieldModelSerializer): required=False, many=True ) - tags = TagListSerializerField(required=False) class Meta: model = Service diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index bc1a8c2e7..30ad82bda 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -486,7 +486,6 @@ SWAGGER_SETTINGS = { 'utilities.custom_inspectors.JSONFieldInspector', 'utilities.custom_inspectors.NullableBooleanFieldInspector', 'utilities.custom_inspectors.CustomChoiceFieldInspector', - 'utilities.custom_inspectors.TagListFieldInspector', 'utilities.custom_inspectors.SerializedPKRelatedFieldInspector', 'drf_yasg.inspectors.CamelCaseJSONFilter', 'drf_yasg.inspectors.ReferencingSerializerInspector', diff --git a/netbox/secrets/api/serializers.py b/netbox/secrets/api/serializers.py index 0b73f0002..54132dd34 100644 --- a/netbox/secrets/api/serializers.py +++ b/netbox/secrets/api/serializers.py @@ -1,8 +1,8 @@ from rest_framework import serializers -from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from dcim.api.nested_serializers import NestedDeviceSerializer from extras.api.customfields import CustomFieldModelSerializer +from extras.api.serializers import TaggedObjectSerializer from secrets.models import Secret, SecretRole from utilities.api import ValidatedModelSerializer from .nested_serializers import * @@ -20,11 +20,10 @@ class SecretRoleSerializer(ValidatedModelSerializer): fields = ['id', 'name', 'slug', 'description', 'secret_count'] -class SecretSerializer(TaggitSerializer, CustomFieldModelSerializer): +class SecretSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): device = NestedDeviceSerializer() role = NestedSecretRoleSerializer() plaintext = serializers.CharField() - tags = TagListSerializerField(required=False) class Meta: model = Secret diff --git a/netbox/tenancy/api/serializers.py b/netbox/tenancy/api/serializers.py index 9c7a099e4..4454ac776 100644 --- a/netbox/tenancy/api/serializers.py +++ b/netbox/tenancy/api/serializers.py @@ -1,7 +1,7 @@ from rest_framework import serializers -from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from extras.api.customfields import CustomFieldModelSerializer +from extras.api.serializers import TaggedObjectSerializer from tenancy.models import Tenant, TenantGroup from utilities.api import ValidatedModelSerializer from .nested_serializers import * @@ -20,9 +20,8 @@ class TenantGroupSerializer(ValidatedModelSerializer): fields = ['id', 'name', 'slug', 'parent', 'description', 'tenant_count'] -class TenantSerializer(TaggitSerializer, CustomFieldModelSerializer): +class TenantSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): group = NestedTenantGroupSerializer(required=False) - tags = TagListSerializerField(required=False) circuit_count = serializers.IntegerField(read_only=True) device_count = serializers.IntegerField(read_only=True) ipaddress_count = serializers.IntegerField(read_only=True) diff --git a/netbox/utilities/custom_inspectors.py b/netbox/utilities/custom_inspectors.py index 2cbe1cfc5..14463de23 100644 --- a/netbox/utilities/custom_inspectors.py +++ b/netbox/utilities/custom_inspectors.py @@ -1,10 +1,9 @@ from django.contrib.postgres.fields import JSONField from drf_yasg import openapi -from drf_yasg.inspectors import FieldInspector, NotHandled, PaginatorInspector, FilterInspector, SwaggerAutoSchema +from drf_yasg.inspectors import FieldInspector, NotHandled, PaginatorInspector, SwaggerAutoSchema from drf_yasg.utils import get_serializer_ref_name from rest_framework.fields import ChoiceField from rest_framework.relations import ManyRelatedField -from taggit_serializer.serializers import TagListSerializerField from dcim.api.serializers import InterfaceSerializer as DeviceInterfaceSerializer from extras.api.customfields import CustomFieldsSerializer @@ -56,19 +55,6 @@ class SerializedPKRelatedFieldInspector(FieldInspector): return NotHandled -class TagListFieldInspector(FieldInspector): - def field_to_swagger_object(self, field, swagger_object_type, use_references, **kwargs): - SwaggerType, ChildSwaggerType = self._get_partial_types(field, swagger_object_type, use_references, **kwargs) - if isinstance(field, TagListSerializerField): - child_schema = self.probe_field_inspectors(field.child, ChildSwaggerType, use_references) - return SwaggerType( - type=openapi.TYPE_ARRAY, - items=child_schema, - ) - - return NotHandled - - class CustomChoiceFieldInspector(FieldInspector): def field_to_swagger_object(self, field, swagger_object_type, use_references, **kwargs): # this returns a callable which extracts title, description and other stuff diff --git a/netbox/virtualization/api/serializers.py b/netbox/virtualization/api/serializers.py index 3cca95b22..008c6dd88 100644 --- a/netbox/virtualization/api/serializers.py +++ b/netbox/virtualization/api/serializers.py @@ -1,11 +1,11 @@ from drf_yasg.utils import swagger_serializer_method from rest_framework import serializers -from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from dcim.api.nested_serializers import NestedDeviceRoleSerializer, NestedPlatformSerializer, NestedSiteSerializer -from dcim.choices import InterfaceModeChoices, InterfaceTypeChoices +from dcim.choices import InterfaceModeChoices from dcim.models import Interface from extras.api.customfields import CustomFieldModelSerializer +from extras.api.serializers import TaggedObjectSerializer from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer from ipam.models import VLAN from tenancy.api.nested_serializers import NestedTenantSerializer @@ -35,12 +35,11 @@ class ClusterGroupSerializer(ValidatedModelSerializer): fields = ['id', 'name', 'slug', 'description', 'cluster_count'] -class ClusterSerializer(TaggitSerializer, CustomFieldModelSerializer): +class ClusterSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): type = NestedClusterTypeSerializer() group = NestedClusterGroupSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True) site = NestedSiteSerializer(required=False, allow_null=True) - tags = TagListSerializerField(required=False) device_count = serializers.IntegerField(read_only=True) virtualmachine_count = serializers.IntegerField(read_only=True) @@ -56,7 +55,7 @@ class ClusterSerializer(TaggitSerializer, CustomFieldModelSerializer): # Virtual machines # -class VirtualMachineSerializer(TaggitSerializer, CustomFieldModelSerializer): +class VirtualMachineSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): status = ChoiceField(choices=VirtualMachineStatusChoices, required=False) site = NestedSiteSerializer(read_only=True) cluster = NestedClusterSerializer() @@ -66,7 +65,6 @@ class VirtualMachineSerializer(TaggitSerializer, CustomFieldModelSerializer): primary_ip = NestedIPAddressSerializer(read_only=True) primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True) primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True) - tags = TagListSerializerField(required=False) class Meta: model = VirtualMachine @@ -97,7 +95,7 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer): # VM interfaces # -class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer): +class InterfaceSerializer(TaggedObjectSerializer, ValidatedModelSerializer): virtual_machine = NestedVirtualMachineSerializer() type = ChoiceField(choices=VMInterfaceTypeChoices, default=VMInterfaceTypeChoices.TYPE_VIRTUAL, required=False) mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False) @@ -108,7 +106,6 @@ class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer): required=False, many=True ) - tags = TagListSerializerField(required=False) class Meta: model = Interface