From 0f37da1523791735834da4007ff264a0ac023e47 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 14 Aug 2024 15:26:16 -0400 Subject: [PATCH] Closes #17143: Deprecate the use of dedicated nested API serializers --- netbox/circuits/api/nested_serializers.py | 21 ++-- netbox/circuits/api/serializers.py | 1 - netbox/circuits/api/serializers_/nested.py | 13 +++ netbox/circuits/api/serializers_/providers.py | 2 +- netbox/core/api/nested_serializers.py | 8 ++ netbox/core/api/serializers.py | 1 - netbox/dcim/api/nested_serializers.py | 94 +++--------------- netbox/dcim/api/serializers.py | 1 - .../api/serializers_/device_components.py | 4 +- netbox/dcim/api/serializers_/devices.py | 2 +- .../api/serializers_/devicetype_components.py | 2 +- netbox/dcim/api/serializers_/nested.py | 98 +++++++++++++++++++ netbox/dcim/api/serializers_/sites.py | 2 +- .../dcim/api/serializers_/virtualchassis.py | 2 +- netbox/extras/api/nested_serializers.py | 8 ++ netbox/extras/api/serializers.py | 1 - netbox/ipam/api/nested_serializers.py | 22 ++--- netbox/ipam/api/serializers.py | 1 - netbox/ipam/api/serializers_/ip.py | 2 +- netbox/ipam/api/serializers_/nested.py | 18 ++++ netbox/netbox/api/serializers/nested.py | 2 +- netbox/tenancy/api/nested_serializers.py | 34 ++----- netbox/tenancy/api/serializers.py | 1 - netbox/tenancy/api/serializers_/contacts.py | 2 +- netbox/tenancy/api/serializers_/nested.py | 34 +++++++ netbox/tenancy/api/serializers_/tenants.py | 2 +- netbox/users/api/nested_serializers.py | 30 ++---- netbox/users/api/serializers.py | 1 - netbox/users/api/serializers_/nested.py | 30 ++++++ netbox/users/api/serializers_/permissions.py | 4 +- .../virtualization/api/nested_serializers.py | 27 ++--- netbox/virtualization/api/serializers.py | 1 - .../virtualization/api/serializers_/nested.py | 22 +++++ .../api/serializers_/virtualmachines.py | 2 +- netbox/vpn/api/nested_serializers.py | 9 +- netbox/vpn/api/serializers.py | 1 - netbox/wireless/api/nested_serializers.py | 25 ++--- netbox/wireless/api/serializers.py | 1 - netbox/wireless/api/serializers_/nested.py | 29 ++++++ .../wireless/api/serializers_/wirelesslans.py | 2 +- 40 files changed, 345 insertions(+), 217 deletions(-) create mode 100644 netbox/circuits/api/serializers_/nested.py create mode 100644 netbox/dcim/api/serializers_/nested.py create mode 100644 netbox/ipam/api/serializers_/nested.py create mode 100644 netbox/tenancy/api/serializers_/nested.py create mode 100644 netbox/users/api/serializers_/nested.py create mode 100644 netbox/virtualization/api/serializers_/nested.py create mode 100644 netbox/wireless/api/serializers_/nested.py diff --git a/netbox/circuits/api/nested_serializers.py b/netbox/circuits/api/nested_serializers.py index 4201b3761..6de2cbf54 100644 --- a/netbox/circuits/api/nested_serializers.py +++ b/netbox/circuits/api/nested_serializers.py @@ -1,9 +1,11 @@ +import warnings + from drf_spectacular.utils import extend_schema_serializer -from rest_framework import serializers from circuits.models import * from netbox.api.fields import RelatedObjectCountField from netbox.api.serializers import WritableNestedSerializer +from .serializers_.nested import NestedProviderAccountSerializer __all__ = [ 'NestedCircuitSerializer', @@ -14,6 +16,12 @@ __all__ = [ 'NestedProviderAccountSerializer', ] +# TODO: Remove in v4.2 +warnings.warn( + f"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.", + DeprecationWarning +) + # # Provider networks @@ -41,17 +49,6 @@ class NestedProviderSerializer(WritableNestedSerializer): fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'circuit_count'] -# -# Provider Accounts -# - -class NestedProviderAccountSerializer(WritableNestedSerializer): - - class Meta: - model = ProviderAccount - fields = ['id', 'url', 'display_url', 'display', 'name', 'account'] - - # # Circuits # diff --git a/netbox/circuits/api/serializers.py b/netbox/circuits/api/serializers.py index 5e048218c..9a2af4a67 100644 --- a/netbox/circuits/api/serializers.py +++ b/netbox/circuits/api/serializers.py @@ -1,3 +1,2 @@ from .serializers_.providers import * from .serializers_.circuits import * -from .nested_serializers import * diff --git a/netbox/circuits/api/serializers_/nested.py b/netbox/circuits/api/serializers_/nested.py new file mode 100644 index 000000000..7f03de942 --- /dev/null +++ b/netbox/circuits/api/serializers_/nested.py @@ -0,0 +1,13 @@ +from circuits.models import ProviderAccount +from netbox.api.serializers import WritableNestedSerializer + +__all__ = ( + 'NestedProviderAccountSerializer', +) + + +class NestedProviderAccountSerializer(WritableNestedSerializer): + + class Meta: + model = ProviderAccount + fields = ['id', 'url', 'display_url', 'display', 'name', 'account'] diff --git a/netbox/circuits/api/serializers_/providers.py b/netbox/circuits/api/serializers_/providers.py index b0e27754b..4e3787107 100644 --- a/netbox/circuits/api/serializers_/providers.py +++ b/netbox/circuits/api/serializers_/providers.py @@ -5,7 +5,7 @@ from ipam.api.serializers_.asns import ASNSerializer from ipam.models import ASN from netbox.api.fields import RelatedObjectCountField, SerializedPKRelatedField from netbox.api.serializers import NetBoxModelSerializer -from ..nested_serializers import * +from .nested import NestedProviderAccountSerializer __all__ = ( 'ProviderAccountSerializer', diff --git a/netbox/core/api/nested_serializers.py b/netbox/core/api/nested_serializers.py index 8e5d3ff63..3b40853cf 100644 --- a/netbox/core/api/nested_serializers.py +++ b/netbox/core/api/nested_serializers.py @@ -1,3 +1,5 @@ +import warnings + from rest_framework import serializers from core.choices import JobStatusChoices @@ -12,6 +14,12 @@ __all__ = ( 'NestedJobSerializer', ) +# TODO: Remove in v4.2 +warnings.warn( + f"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.", + DeprecationWarning +) + class NestedDataSourceSerializer(WritableNestedSerializer): diff --git a/netbox/core/api/serializers.py b/netbox/core/api/serializers.py index d59745ccd..2dde6be9f 100644 --- a/netbox/core/api/serializers.py +++ b/netbox/core/api/serializers.py @@ -1,4 +1,3 @@ from .serializers_.change_logging import * from .serializers_.data import * from .serializers_.jobs import * -from .nested_serializers import * diff --git a/netbox/dcim/api/nested_serializers.py b/netbox/dcim/api/nested_serializers.py index 6aff1bdc9..5d83b9145 100644 --- a/netbox/dcim/api/nested_serializers.py +++ b/netbox/dcim/api/nested_serializers.py @@ -1,9 +1,15 @@ +import warnings + from drf_spectacular.utils import extend_schema_serializer from rest_framework import serializers from dcim import models from netbox.api.fields import RelatedObjectCountField from netbox.api.serializers import WritableNestedSerializer +from .serializers_.nested import ( + NestedDeviceBaySerializer, NestedDeviceSerializer, NestedInterfaceSerializer, NestedInterfaceTemplateSerializer, + NestedLocationSerializer, NestedModuleBaySerializer, NestedRegionSerializer, NestedSiteGroupSerializer, +) __all__ = [ 'NestedCableSerializer', @@ -48,35 +54,17 @@ __all__ = [ 'NestedVirtualDeviceContextSerializer', ] +# TODO: Remove in v4.2 +warnings.warn( + f"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.", + DeprecationWarning +) + # # Regions/sites # -@extend_schema_serializer( - exclude_fields=('site_count',), -) -class NestedRegionSerializer(WritableNestedSerializer): - site_count = serializers.IntegerField(read_only=True) - _depth = serializers.IntegerField(source='level', read_only=True) - - class Meta: - model = models.Region - fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'site_count', '_depth'] - - -@extend_schema_serializer( - exclude_fields=('site_count',), -) -class NestedSiteGroupSerializer(WritableNestedSerializer): - site_count = serializers.IntegerField(read_only=True) - _depth = serializers.IntegerField(source='level', read_only=True) - - class Meta: - model = models.SiteGroup - fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'site_count', '_depth'] - - class NestedSiteSerializer(WritableNestedSerializer): class Meta: @@ -88,18 +76,6 @@ class NestedSiteSerializer(WritableNestedSerializer): # Racks # -@extend_schema_serializer( - exclude_fields=('rack_count',), -) -class NestedLocationSerializer(WritableNestedSerializer): - rack_count = serializers.IntegerField(read_only=True) - _depth = serializers.IntegerField(source='level', read_only=True) - - class Meta: - model = models.Location - fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'rack_count', '_depth'] - - @extend_schema_serializer( exclude_fields=('rack_count',), ) @@ -200,13 +176,6 @@ class NestedPowerOutletTemplateSerializer(WritableNestedSerializer): fields = ['id', 'url', 'display_url', 'display', 'name'] -class NestedInterfaceTemplateSerializer(WritableNestedSerializer): - - class Meta: - model = models.InterfaceTemplate - fields = ['id', 'url', 'display_url', 'display', 'name'] - - class NestedRearPortTemplateSerializer(WritableNestedSerializer): class Meta: @@ -271,13 +240,6 @@ class NestedPlatformSerializer(WritableNestedSerializer): fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'device_count', 'virtualmachine_count'] -class NestedDeviceSerializer(WritableNestedSerializer): - - class Meta: - model = models.Device - fields = ['id', 'url', 'display_url', 'display', 'name'] - - class ModuleNestedModuleBaySerializer(WritableNestedSerializer): class Meta: @@ -285,13 +247,6 @@ class ModuleNestedModuleBaySerializer(WritableNestedSerializer): fields = ['id', 'url', 'display_url', 'display', 'name'] -class ModuleBayNestedModuleSerializer(WritableNestedSerializer): - - class Meta: - model = models.Module - fields = ['id', 'url', 'display_url', 'display', 'serial'] - - class NestedModuleSerializer(WritableNestedSerializer): device = NestedDeviceSerializer(read_only=True) module_bay = ModuleNestedModuleBaySerializer(read_only=True) @@ -338,15 +293,6 @@ class NestedPowerPortSerializer(WritableNestedSerializer): fields = ['id', 'url', 'display_url', 'display', 'device', 'name', 'cable', '_occupied'] -class NestedInterfaceSerializer(WritableNestedSerializer): - device = NestedDeviceSerializer(read_only=True) - _occupied = serializers.BooleanField(required=False, read_only=True) - - class Meta: - model = models.Interface - fields = ['id', 'url', 'display_url', 'display', 'device', 'name', 'cable', '_occupied'] - - class NestedRearPortSerializer(WritableNestedSerializer): device = NestedDeviceSerializer(read_only=True) _occupied = serializers.BooleanField(required=False, read_only=True) @@ -365,22 +311,6 @@ class NestedFrontPortSerializer(WritableNestedSerializer): fields = ['id', 'url', 'display_url', 'display', 'device', 'name', 'cable', '_occupied'] -class NestedModuleBaySerializer(WritableNestedSerializer): - installed_module = ModuleBayNestedModuleSerializer(required=False, allow_null=True) - - class Meta: - model = models.ModuleBay - fields = ['id', 'url', 'display_url', 'display', 'installed_module', 'name'] - - -class NestedDeviceBaySerializer(WritableNestedSerializer): - device = NestedDeviceSerializer(read_only=True) - - class Meta: - model = models.DeviceBay - fields = ['id', 'url', 'display_url', 'display', 'device', 'name'] - - class NestedInventoryItemSerializer(WritableNestedSerializer): device = NestedDeviceSerializer(read_only=True) _depth = serializers.IntegerField(source='level', read_only=True) diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 4f8bbac17..30aa2e1a0 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -11,4 +11,3 @@ from .serializers_.devices import * from .serializers_.device_components import * from .serializers_.power import * from .serializers_.rackunits import * -from .nested_serializers import * diff --git a/netbox/dcim/api/serializers_/device_components.py b/netbox/dcim/api/serializers_/device_components.py index 06451043b..e7992e4b3 100644 --- a/netbox/dcim/api/serializers_/device_components.py +++ b/netbox/dcim/api/serializers_/device_components.py @@ -15,7 +15,7 @@ from netbox.api.fields import ChoiceField, ContentTypeField, SerializedPKRelated from netbox.api.serializers import NetBoxModelSerializer, WritableNestedSerializer from utilities.api import get_serializer_for_model from vpn.api.serializers_.l2vpn import L2VPNTerminationSerializer -from wireless.api.nested_serializers import NestedWirelessLinkSerializer +from wireless.api.serializers_.nested import NestedWirelessLinkSerializer from wireless.api.serializers_.wirelesslans import WirelessLANSerializer from wireless.choices import * from wireless.models import WirelessLAN @@ -23,8 +23,8 @@ from .base import ConnectedEndpointsSerializer from .cables import CabledObjectSerializer from .devices import DeviceSerializer, ModuleSerializer, VirtualDeviceContextSerializer from .manufacturers import ManufacturerSerializer +from .nested import NestedInterfaceSerializer from .roles import InventoryItemRoleSerializer -from ..nested_serializers import * __all__ = ( 'ConsolePortSerializer', diff --git a/netbox/dcim/api/serializers_/devices.py b/netbox/dcim/api/serializers_/devices.py index 684b467db..7a01b49e8 100644 --- a/netbox/dcim/api/serializers_/devices.py +++ b/netbox/dcim/api/serializers_/devices.py @@ -16,9 +16,9 @@ from .devicetypes import * from .platforms import PlatformSerializer from .racks import RackSerializer from .roles import DeviceRoleSerializer +from .nested import NestedDeviceBaySerializer, NestedDeviceSerializer, NestedModuleBaySerializer from .sites import LocationSerializer, SiteSerializer from .virtualchassis import VirtualChassisSerializer -from ..nested_serializers import * __all__ = ( 'DeviceSerializer', diff --git a/netbox/dcim/api/serializers_/devicetype_components.py b/netbox/dcim/api/serializers_/devicetype_components.py index f4d09e7fb..04f6395a6 100644 --- a/netbox/dcim/api/serializers_/devicetype_components.py +++ b/netbox/dcim/api/serializers_/devicetype_components.py @@ -14,8 +14,8 @@ from utilities.api import get_serializer_for_model from wireless.choices import * from .devicetypes import DeviceTypeSerializer, ModuleTypeSerializer from .manufacturers import ManufacturerSerializer +from .nested import NestedInterfaceTemplateSerializer from .roles import InventoryItemRoleSerializer -from ..nested_serializers import * __all__ = ( 'ConsolePortTemplateSerializer', diff --git a/netbox/dcim/api/serializers_/nested.py b/netbox/dcim/api/serializers_/nested.py new file mode 100644 index 000000000..bfbb350c4 --- /dev/null +++ b/netbox/dcim/api/serializers_/nested.py @@ -0,0 +1,98 @@ +from drf_spectacular.utils import extend_schema_serializer +from rest_framework import serializers + +from netbox.api.serializers import WritableNestedSerializer +from dcim import models + +__all__ = ( + 'NestedDeviceBaySerializer', + 'NestedDeviceSerializer', + 'NestedInterfaceSerializer', + 'NestedInterfaceTemplateSerializer', + 'NestedLocationSerializer', + 'NestedModuleBaySerializer', + 'NestedRegionSerializer', + 'NestedSiteGroupSerializer', +) + + +@extend_schema_serializer( + exclude_fields=('site_count',), +) +class NestedRegionSerializer(WritableNestedSerializer): + site_count = serializers.IntegerField(read_only=True) + _depth = serializers.IntegerField(source='level', read_only=True) + + class Meta: + model = models.Region + fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'site_count', '_depth'] + + +@extend_schema_serializer( + exclude_fields=('site_count',), +) +class NestedSiteGroupSerializer(WritableNestedSerializer): + site_count = serializers.IntegerField(read_only=True) + _depth = serializers.IntegerField(source='level', read_only=True) + + class Meta: + model = models.SiteGroup + fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'site_count', '_depth'] + + +@extend_schema_serializer( + exclude_fields=('rack_count',), +) +class NestedLocationSerializer(WritableNestedSerializer): + rack_count = serializers.IntegerField(read_only=True) + _depth = serializers.IntegerField(source='level', read_only=True) + + class Meta: + model = models.Location + fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'rack_count', '_depth'] + + +class NestedDeviceSerializer(WritableNestedSerializer): + + class Meta: + model = models.Device + fields = ['id', 'url', 'display_url', 'display', 'name'] + + +class NestedInterfaceSerializer(WritableNestedSerializer): + device = NestedDeviceSerializer(read_only=True) + _occupied = serializers.BooleanField(required=False, read_only=True) + + class Meta: + model = models.Interface + fields = ['id', 'url', 'display_url', 'display', 'device', 'name', 'cable', '_occupied'] + + +class NestedInterfaceTemplateSerializer(WritableNestedSerializer): + + class Meta: + model = models.InterfaceTemplate + fields = ['id', 'url', 'display_url', 'display', 'name'] + + +class NestedDeviceBaySerializer(WritableNestedSerializer): + device = NestedDeviceSerializer(read_only=True) + + class Meta: + model = models.DeviceBay + fields = ['id', 'url', 'display_url', 'display', 'device', 'name'] + + +class ModuleBayNestedModuleSerializer(WritableNestedSerializer): + + class Meta: + model = models.Module + fields = ['id', 'url', 'display_url', 'display', 'serial'] + + +class NestedModuleBaySerializer(WritableNestedSerializer): + installed_module = ModuleBayNestedModuleSerializer(required=False, allow_null=True) + + class Meta: + model = models.ModuleBay + fields = ['id', 'url', 'display_url', 'display', 'installed_module', 'name'] diff --git a/netbox/dcim/api/serializers_/sites.py b/netbox/dcim/api/serializers_/sites.py index f45a1949d..dc91f5dc7 100644 --- a/netbox/dcim/api/serializers_/sites.py +++ b/netbox/dcim/api/serializers_/sites.py @@ -8,7 +8,7 @@ from ipam.models import ASN from netbox.api.fields import ChoiceField, RelatedObjectCountField, SerializedPKRelatedField from netbox.api.serializers import NestedGroupModelSerializer, NetBoxModelSerializer from tenancy.api.serializers_.tenants import TenantSerializer -from ..nested_serializers import * +from .nested import NestedLocationSerializer, NestedRegionSerializer, NestedSiteGroupSerializer __all__ = ( 'LocationSerializer', diff --git a/netbox/dcim/api/serializers_/virtualchassis.py b/netbox/dcim/api/serializers_/virtualchassis.py index 19e94ba8d..a93d2833f 100644 --- a/netbox/dcim/api/serializers_/virtualchassis.py +++ b/netbox/dcim/api/serializers_/virtualchassis.py @@ -2,7 +2,7 @@ from rest_framework import serializers from dcim.models import VirtualChassis from netbox.api.serializers import NetBoxModelSerializer -from ..nested_serializers import * +from .nested import NestedDeviceSerializer __all__ = ( 'VirtualChassisSerializer', diff --git a/netbox/extras/api/nested_serializers.py b/netbox/extras/api/nested_serializers.py index 3904493c0..ba291b34e 100644 --- a/netbox/extras/api/nested_serializers.py +++ b/netbox/extras/api/nested_serializers.py @@ -1,3 +1,5 @@ +import warnings + from rest_framework import serializers from extras import models @@ -20,6 +22,12 @@ __all__ = [ 'NestedWebhookSerializer', ] +# TODO: Remove in v4.2 +warnings.warn( + f"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.", + DeprecationWarning +) + class NestedEventRuleSerializer(WritableNestedSerializer): diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index f1b0e0894..5e799b504 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -13,4 +13,3 @@ from .serializers_.configtemplates import * from .serializers_.savedfilters import * from .serializers_.scripts import * from .serializers_.tags import * -from .nested_serializers import * diff --git a/netbox/ipam/api/nested_serializers.py b/netbox/ipam/api/nested_serializers.py index 95b5ab11d..57a1a65d5 100644 --- a/netbox/ipam/api/nested_serializers.py +++ b/netbox/ipam/api/nested_serializers.py @@ -1,3 +1,5 @@ +import warnings + from drf_spectacular.utils import extend_schema_serializer from rest_framework import serializers @@ -5,6 +7,7 @@ from ipam import models from netbox.api.fields import RelatedObjectCountField from netbox.api.serializers import WritableNestedSerializer from .field_serializers import IPAddressField +from .serializers_.nested import NestedIPAddressSerializer __all__ = [ 'NestedAggregateSerializer', @@ -25,6 +28,12 @@ __all__ = [ 'NestedVRFSerializer', ] +# TODO: Remove in v4.2 +warnings.warn( + f"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.", + DeprecationWarning +) + # # ASN ranges @@ -177,19 +186,6 @@ class NestedIPRangeSerializer(WritableNestedSerializer): fields = ['id', 'url', 'display_url', 'display', 'family', 'start_address', 'end_address'] -# -# IP addresses -# - -class NestedIPAddressSerializer(WritableNestedSerializer): - family = serializers.IntegerField(read_only=True) - address = IPAddressField() - - class Meta: - model = models.IPAddress - fields = ['id', 'url', 'display_url', 'display', 'family', 'address'] - - # # Services # diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index 1f5f21028..0bdfc5385 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -5,4 +5,3 @@ from .serializers_.vlans import * from .serializers_.ip import * from .serializers_.fhrpgroups import * from .serializers_.services import * -from .nested_serializers import * diff --git a/netbox/ipam/api/serializers_/ip.py b/netbox/ipam/api/serializers_/ip.py index 73fd09064..535ffcec1 100644 --- a/netbox/ipam/api/serializers_/ip.py +++ b/netbox/ipam/api/serializers_/ip.py @@ -11,11 +11,11 @@ from netbox.api.serializers import NetBoxModelSerializer from tenancy.api.serializers_.tenants import TenantSerializer from utilities.api import get_serializer_for_model from .asns import RIRSerializer +from .nested import NestedIPAddressSerializer from .roles import RoleSerializer from .vlans import VLANSerializer from .vrfs import VRFSerializer from ..field_serializers import IPAddressField, IPNetworkField -from ..nested_serializers import * __all__ = ( 'AggregateSerializer', diff --git a/netbox/ipam/api/serializers_/nested.py b/netbox/ipam/api/serializers_/nested.py new file mode 100644 index 000000000..5297565bb --- /dev/null +++ b/netbox/ipam/api/serializers_/nested.py @@ -0,0 +1,18 @@ +from rest_framework import serializers + +from ipam import models +from netbox.api.serializers import WritableNestedSerializer +from ..field_serializers import IPAddressField + +__all__ = ( + 'NestedIPAddressSerializer', +) + + +class NestedIPAddressSerializer(WritableNestedSerializer): + family = serializers.IntegerField(read_only=True) + address = IPAddressField() + + class Meta: + model = models.IPAddress + fields = ['id', 'url', 'display_url', 'display', 'family', 'address'] diff --git a/netbox/netbox/api/serializers/nested.py b/netbox/netbox/api/serializers/nested.py index af4ae35cb..04033c71f 100644 --- a/netbox/netbox/api/serializers/nested.py +++ b/netbox/netbox/api/serializers/nested.py @@ -21,7 +21,7 @@ class WritableNestedSerializer(BaseModelSerializer): return get_related_object_by_attrs(queryset, data) -# Declared here for use by PrimaryModelSerializer, but should be imported from extras.api.nested_serializers +# Declared here for use by PrimaryModelSerializer class NestedTagSerializer(WritableNestedSerializer): class Meta: diff --git a/netbox/tenancy/api/nested_serializers.py b/netbox/tenancy/api/nested_serializers.py index d88e969aa..5f339ecba 100644 --- a/netbox/tenancy/api/nested_serializers.py +++ b/netbox/tenancy/api/nested_serializers.py @@ -1,7 +1,7 @@ -from drf_spectacular.utils import extend_schema_serializer -from rest_framework import serializers +import warnings from netbox.api.serializers import WritableNestedSerializer +from serializers_.nested import NestedContactGroupSerializer, NestedTenantGroupSerializer from tenancy.models import * __all__ = [ @@ -13,23 +13,17 @@ __all__ = [ 'NestedTenantSerializer', ] +# TODO: Remove in v4.2 +warnings.warn( + f"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.", + DeprecationWarning +) + # # Tenants # -@extend_schema_serializer( - exclude_fields=('tenant_count',), -) -class NestedTenantGroupSerializer(WritableNestedSerializer): - tenant_count = serializers.IntegerField(read_only=True) - _depth = serializers.IntegerField(source='level', read_only=True) - - class Meta: - model = TenantGroup - fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'tenant_count', '_depth'] - - class NestedTenantSerializer(WritableNestedSerializer): class Meta: @@ -41,18 +35,6 @@ class NestedTenantSerializer(WritableNestedSerializer): # Contacts # -@extend_schema_serializer( - exclude_fields=('contact_count',), -) -class NestedContactGroupSerializer(WritableNestedSerializer): - contact_count = serializers.IntegerField(read_only=True) - _depth = serializers.IntegerField(source='level', read_only=True) - - class Meta: - model = ContactGroup - fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'contact_count', '_depth'] - - class NestedContactRoleSerializer(WritableNestedSerializer): class Meta: diff --git a/netbox/tenancy/api/serializers.py b/netbox/tenancy/api/serializers.py index 642397733..025a858b9 100644 --- a/netbox/tenancy/api/serializers.py +++ b/netbox/tenancy/api/serializers.py @@ -1,3 +1,2 @@ from .serializers_.tenants import * from .serializers_.contacts import * -from .nested_serializers import * diff --git a/netbox/tenancy/api/serializers_/contacts.py b/netbox/tenancy/api/serializers_/contacts.py index b19622e14..8c24df734 100644 --- a/netbox/tenancy/api/serializers_/contacts.py +++ b/netbox/tenancy/api/serializers_/contacts.py @@ -8,7 +8,7 @@ from netbox.api.serializers import NestedGroupModelSerializer, NetBoxModelSerial from tenancy.choices import ContactPriorityChoices from tenancy.models import ContactAssignment, Contact, ContactGroup, ContactRole from utilities.api import get_serializer_for_model -from ..nested_serializers import * +from .nested import NestedContactGroupSerializer __all__ = ( 'ContactAssignmentSerializer', diff --git a/netbox/tenancy/api/serializers_/nested.py b/netbox/tenancy/api/serializers_/nested.py new file mode 100644 index 000000000..7a2f04419 --- /dev/null +++ b/netbox/tenancy/api/serializers_/nested.py @@ -0,0 +1,34 @@ +from drf_spectacular.utils import extend_schema_serializer +from rest_framework import serializers + +from netbox.api.serializers import WritableNestedSerializer +from tenancy import models + +__all__ = ( + 'NestedContactGroupSerializer', + 'NestedTenantGroupSerializer', +) + + +@extend_schema_serializer( + exclude_fields=('contact_count',), +) +class NestedContactGroupSerializer(WritableNestedSerializer): + contact_count = serializers.IntegerField(read_only=True) + _depth = serializers.IntegerField(source='level', read_only=True) + + class Meta: + model = models.ContactGroup + fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'contact_count', '_depth'] + + +@extend_schema_serializer( + exclude_fields=('tenant_count',), +) +class NestedTenantGroupSerializer(WritableNestedSerializer): + tenant_count = serializers.IntegerField(read_only=True) + _depth = serializers.IntegerField(source='level', read_only=True) + + class Meta: + model = models.TenantGroup + fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'tenant_count', '_depth'] diff --git a/netbox/tenancy/api/serializers_/tenants.py b/netbox/tenancy/api/serializers_/tenants.py index 2ccac0d59..54e906f1d 100644 --- a/netbox/tenancy/api/serializers_/tenants.py +++ b/netbox/tenancy/api/serializers_/tenants.py @@ -3,7 +3,7 @@ from rest_framework import serializers from netbox.api.fields import RelatedObjectCountField from netbox.api.serializers import NestedGroupModelSerializer, NetBoxModelSerializer from tenancy.models import Tenant, TenantGroup -from ..nested_serializers import * +from .nested import NestedTenantGroupSerializer __all__ = ( 'TenantGroupSerializer', diff --git a/netbox/users/api/nested_serializers.py b/netbox/users/api/nested_serializers.py index b14cbcdb6..2a5763476 100644 --- a/netbox/users/api/nested_serializers.py +++ b/netbox/users/api/nested_serializers.py @@ -1,11 +1,13 @@ -from drf_spectacular.types import OpenApiTypes +import warnings + from drf_spectacular.utils import extend_schema_field from rest_framework import serializers from core.models import ObjectType from netbox.api.fields import ContentTypeField from netbox.api.serializers import WritableNestedSerializer -from users.models import Group, ObjectPermission, Token, User +from serializers_.nested import NestedGroupSerializer, NestedUserSerializer +from users.models import ObjectPermission, Token __all__ = [ 'NestedGroupSerializer', @@ -14,25 +16,11 @@ __all__ = [ 'NestedUserSerializer', ] - -class NestedGroupSerializer(WritableNestedSerializer): - - class Meta: - model = Group - fields = ['id', 'url', 'display_url', 'display', 'name'] - - -class NestedUserSerializer(WritableNestedSerializer): - - class Meta: - model = User - fields = ['id', 'url', 'display_url', 'display', 'username'] - - @extend_schema_field(OpenApiTypes.STR) - def get_display(self, obj): - if full_name := obj.get_full_name(): - return f"{obj.username} ({full_name})" - return obj.username +# TODO: Remove in v4.2 +warnings.warn( + f"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.", + DeprecationWarning +) class NestedTokenSerializer(WritableNestedSerializer): diff --git a/netbox/users/api/serializers.py b/netbox/users/api/serializers.py index ef3f66a7d..700061b8c 100644 --- a/netbox/users/api/serializers.py +++ b/netbox/users/api/serializers.py @@ -1,4 +1,3 @@ from .serializers_.users import * from .serializers_.permissions import * from .serializers_.tokens import * -from .nested_serializers import * diff --git a/netbox/users/api/serializers_/nested.py b/netbox/users/api/serializers_/nested.py new file mode 100644 index 000000000..b268776b5 --- /dev/null +++ b/netbox/users/api/serializers_/nested.py @@ -0,0 +1,30 @@ +from drf_spectacular.types import OpenApiTypes +from drf_spectacular.utils import extend_schema_field + +from netbox.api.serializers import WritableNestedSerializer +from users import models + +__all__ = ( + 'NestedGroupSerializer', + 'NestedUserSerializer', +) + + +class NestedGroupSerializer(WritableNestedSerializer): + + class Meta: + model = models.Group + fields = ['id', 'url', 'display_url', 'display', 'name'] + + +class NestedUserSerializer(WritableNestedSerializer): + + class Meta: + model = models.User + fields = ['id', 'url', 'display_url', 'display', 'username'] + + @extend_schema_field(OpenApiTypes.STR) + def get_display(self, obj): + if full_name := obj.get_full_name(): + return f"{obj.username} ({full_name})" + return obj.username diff --git a/netbox/users/api/serializers_/permissions.py b/netbox/users/api/serializers_/permissions.py index b6f9de74c..8f3bd13a8 100644 --- a/netbox/users/api/serializers_/permissions.py +++ b/netbox/users/api/serializers_/permissions.py @@ -1,10 +1,8 @@ -from rest_framework import serializers - from core.models import ObjectType from netbox.api.fields import ContentTypeField, SerializedPKRelatedField from netbox.api.serializers import ValidatedModelSerializer -from users.api.nested_serializers import NestedGroupSerializer, NestedUserSerializer from users.models import Group, ObjectPermission, User +from .nested import NestedGroupSerializer, NestedUserSerializer __all__ = ( 'ObjectPermissionSerializer', diff --git a/netbox/virtualization/api/nested_serializers.py b/netbox/virtualization/api/nested_serializers.py index 4c070c85c..a2395faa5 100644 --- a/netbox/virtualization/api/nested_serializers.py +++ b/netbox/virtualization/api/nested_serializers.py @@ -1,9 +1,11 @@ +import warnings + from drf_spectacular.utils import extend_schema_serializer -from rest_framework import serializers from netbox.api.fields import RelatedObjectCountField from netbox.api.serializers import WritableNestedSerializer from virtualization.models import * +from .serializers_.nested import NestedVirtualMachineSerializer, NestedVMInterfaceSerializer __all__ = [ 'NestedClusterGroupSerializer', @@ -14,11 +16,17 @@ __all__ = [ 'NestedVirtualMachineSerializer', ] +# TODO: Remove in v4.2 +warnings.warn( + f"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.", + DeprecationWarning +) + + # # Clusters # - @extend_schema_serializer( exclude_fields=('cluster_count',), ) @@ -56,21 +64,6 @@ class NestedClusterSerializer(WritableNestedSerializer): # Virtual machines # -class NestedVirtualMachineSerializer(WritableNestedSerializer): - - class Meta: - model = VirtualMachine - fields = ['id', 'url', 'display_url', 'display', 'name'] - - -class NestedVMInterfaceSerializer(WritableNestedSerializer): - virtual_machine = NestedVirtualMachineSerializer(read_only=True) - - class Meta: - model = VMInterface - fields = ['id', 'url', 'display_url', 'display', 'virtual_machine', 'name'] - - class NestedVirtualDiskSerializer(WritableNestedSerializer): virtual_machine = NestedVirtualMachineSerializer(read_only=True) diff --git a/netbox/virtualization/api/serializers.py b/netbox/virtualization/api/serializers.py index ad698fe2f..57b8cb4d0 100644 --- a/netbox/virtualization/api/serializers.py +++ b/netbox/virtualization/api/serializers.py @@ -1,3 +1,2 @@ from .serializers_.clusters import * from .serializers_.virtualmachines import * -from .nested_serializers import * diff --git a/netbox/virtualization/api/serializers_/nested.py b/netbox/virtualization/api/serializers_/nested.py new file mode 100644 index 000000000..f09a48299 --- /dev/null +++ b/netbox/virtualization/api/serializers_/nested.py @@ -0,0 +1,22 @@ +from netbox.api.serializers import WritableNestedSerializer +from virtualization import models + +__all__ = ( + 'NestedVirtualMachineSerializer', + 'NestedVMInterfaceSerializer', +) + + +class NestedVirtualMachineSerializer(WritableNestedSerializer): + + class Meta: + model = models.VirtualMachine + fields = ['id', 'url', 'display_url', 'display', 'name'] + + +class NestedVMInterfaceSerializer(WritableNestedSerializer): + virtual_machine = NestedVirtualMachineSerializer(read_only=True) + + class Meta: + model = models.VMInterface + fields = ['id', 'url', 'display_url', 'display', 'virtual_machine', 'name'] diff --git a/netbox/virtualization/api/serializers_/virtualmachines.py b/netbox/virtualization/api/serializers_/virtualmachines.py index 65e0fc965..1b224c16a 100644 --- a/netbox/virtualization/api/serializers_/virtualmachines.py +++ b/netbox/virtualization/api/serializers_/virtualmachines.py @@ -18,7 +18,7 @@ from virtualization.choices import * from virtualization.models import VirtualDisk, VirtualMachine, VMInterface from vpn.api.serializers_.l2vpn import L2VPNTerminationSerializer from .clusters import ClusterSerializer -from ..nested_serializers import * +from .nested import NestedVMInterfaceSerializer __all__ = ( 'VMInterfaceSerializer', diff --git a/netbox/vpn/api/nested_serializers.py b/netbox/vpn/api/nested_serializers.py index 2c7e3eb03..c1a90cbea 100644 --- a/netbox/vpn/api/nested_serializers.py +++ b/netbox/vpn/api/nested_serializers.py @@ -1,5 +1,6 @@ +import warnings + from drf_spectacular.utils import extend_schema_serializer -from rest_framework import serializers from netbox.api.fields import RelatedObjectCountField from netbox.api.serializers import WritableNestedSerializer @@ -18,6 +19,12 @@ __all__ = ( 'NestedTunnelTerminationSerializer', ) +# TODO: Remove in v4.2 +warnings.warn( + f"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.", + DeprecationWarning +) + @extend_schema_serializer( exclude_fields=('tunnel_count',), diff --git a/netbox/vpn/api/serializers.py b/netbox/vpn/api/serializers.py index 8a7e21e63..9e4afa8f8 100644 --- a/netbox/vpn/api/serializers.py +++ b/netbox/vpn/api/serializers.py @@ -1,4 +1,3 @@ from .serializers_.crypto import * from .serializers_.tunnels import * from .serializers_.l2vpn import * -from .nested_serializers import * diff --git a/netbox/wireless/api/nested_serializers.py b/netbox/wireless/api/nested_serializers.py index 8196b9828..433164e60 100644 --- a/netbox/wireless/api/nested_serializers.py +++ b/netbox/wireless/api/nested_serializers.py @@ -1,8 +1,8 @@ -from drf_spectacular.utils import extend_schema_serializer -from rest_framework import serializers +import warnings from netbox.api.serializers import WritableNestedSerializer from wireless.models import * +from .serializers_.nested import NestedWirelessLANGroupSerializer, NestedWirelessLinkSerializer __all__ = ( 'NestedWirelessLANSerializer', @@ -10,17 +10,11 @@ __all__ = ( 'NestedWirelessLinkSerializer', ) - -@extend_schema_serializer( - exclude_fields=('wirelesslan_count',), +# TODO: Remove in v4.2 +warnings.warn( + f"Dedicated nested serializers will be removed in NetBox v4.2. Use Serializer(nested=True) instead.", + DeprecationWarning ) -class NestedWirelessLANGroupSerializer(WritableNestedSerializer): - wirelesslan_count = serializers.IntegerField(read_only=True) - _depth = serializers.IntegerField(source='level', read_only=True) - - class Meta: - model = WirelessLANGroup - fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'wirelesslan_count', '_depth'] class NestedWirelessLANSerializer(WritableNestedSerializer): @@ -28,10 +22,3 @@ class NestedWirelessLANSerializer(WritableNestedSerializer): class Meta: model = WirelessLAN fields = ['id', 'url', 'display_url', 'display', 'ssid'] - - -class NestedWirelessLinkSerializer(WritableNestedSerializer): - - class Meta: - model = WirelessLink - fields = ['id', 'url', 'display_url', 'display', 'ssid'] diff --git a/netbox/wireless/api/serializers.py b/netbox/wireless/api/serializers.py index 8c864d059..f8b4f9267 100644 --- a/netbox/wireless/api/serializers.py +++ b/netbox/wireless/api/serializers.py @@ -1,3 +1,2 @@ from .serializers_.wirelesslans import * from .serializers_.wirelesslinks import * -from .nested_serializers import * diff --git a/netbox/wireless/api/serializers_/nested.py b/netbox/wireless/api/serializers_/nested.py new file mode 100644 index 000000000..b836a5932 --- /dev/null +++ b/netbox/wireless/api/serializers_/nested.py @@ -0,0 +1,29 @@ +from drf_spectacular.utils import extend_schema_serializer +from rest_framework import serializers + +from netbox.api.serializers import WritableNestedSerializer +from wireless import models + +__all__ = ( + 'NestedWirelessLANGroupSerializer', + 'NestedWirelessLinkSerializer', +) + + +@extend_schema_serializer( + exclude_fields=('wirelesslan_count',), +) +class NestedWirelessLANGroupSerializer(WritableNestedSerializer): + wirelesslan_count = serializers.IntegerField(read_only=True) + _depth = serializers.IntegerField(source='level', read_only=True) + + class Meta: + model = models.WirelessLANGroup + fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'wirelesslan_count', '_depth'] + + +class NestedWirelessLinkSerializer(WritableNestedSerializer): + + class Meta: + model = models.WirelessLink + fields = ['id', 'url', 'display_url', 'display', 'ssid'] diff --git a/netbox/wireless/api/serializers_/wirelesslans.py b/netbox/wireless/api/serializers_/wirelesslans.py index 9f6b9c009..6c5deeb26 100644 --- a/netbox/wireless/api/serializers_/wirelesslans.py +++ b/netbox/wireless/api/serializers_/wirelesslans.py @@ -6,7 +6,7 @@ from netbox.api.serializers import NestedGroupModelSerializer, NetBoxModelSerial from tenancy.api.serializers_.tenants import TenantSerializer from wireless.choices import * from wireless.models import WirelessLAN, WirelessLANGroup -from ..nested_serializers import * +from .nested import NestedWirelessLANGroupSerializer __all__ = ( 'WirelessLANGroupSerializer',