mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
* Enable dynamic field inclusion for REST API serializers * Recurse through nested serializer when resolving prefetches * Remove obsolete calls to prefetch_related() for API views * Remove support for brief_prefetch_fields viewset attribute * Rename query parameter * Fixes #15133: Fix FHRP group representation on assignments endpoint under brief mode (#15134) * Fixes #15133: Fix FHRP group representation on assignments endpoint under brief mode * Update API test * Restore get_queryset() on BriefModeMixin, minus prefetch logic * get_prefetches_for_serializer() should reference serializer field source if set
This commit is contained in:
@ -21,7 +21,7 @@ class CircuitsRootView(APIRootView):
|
||||
#
|
||||
|
||||
class ProviderViewSet(NetBoxModelViewSet):
|
||||
queryset = Provider.objects.prefetch_related('asns', 'tags').annotate(
|
||||
queryset = Provider.objects.annotate(
|
||||
circuit_count=count_related(Circuit, 'provider')
|
||||
)
|
||||
serializer_class = serializers.ProviderSerializer
|
||||
@ -33,7 +33,7 @@ class ProviderViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class CircuitTypeViewSet(NetBoxModelViewSet):
|
||||
queryset = CircuitType.objects.prefetch_related('tags').annotate(
|
||||
queryset = CircuitType.objects.annotate(
|
||||
circuit_count=count_related(Circuit, 'type')
|
||||
)
|
||||
serializer_class = serializers.CircuitTypeSerializer
|
||||
@ -45,9 +45,7 @@ class CircuitTypeViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class CircuitViewSet(NetBoxModelViewSet):
|
||||
queryset = Circuit.objects.prefetch_related(
|
||||
'type', 'tenant', 'provider', 'provider_account', 'termination_a', 'termination_z'
|
||||
).prefetch_related('tags')
|
||||
queryset = Circuit.objects.all()
|
||||
serializer_class = serializers.CircuitSerializer
|
||||
filterset_class = filtersets.CircuitFilterSet
|
||||
|
||||
@ -57,12 +55,9 @@ class CircuitViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class CircuitTerminationViewSet(PassThroughPortMixin, NetBoxModelViewSet):
|
||||
queryset = CircuitTermination.objects.prefetch_related(
|
||||
'circuit', 'site', 'provider_network', 'cable__terminations'
|
||||
)
|
||||
queryset = CircuitTermination.objects.all()
|
||||
serializer_class = serializers.CircuitTerminationSerializer
|
||||
filterset_class = filtersets.CircuitTerminationFilterSet
|
||||
brief_prefetch_fields = ['circuit']
|
||||
|
||||
|
||||
#
|
||||
@ -70,7 +65,7 @@ class CircuitTerminationViewSet(PassThroughPortMixin, NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class ProviderAccountViewSet(NetBoxModelViewSet):
|
||||
queryset = ProviderAccount.objects.prefetch_related('provider', 'tags')
|
||||
queryset = ProviderAccount.objects.all()
|
||||
serializer_class = serializers.ProviderAccountSerializer
|
||||
filterset_class = filtersets.ProviderAccountFilterSet
|
||||
|
||||
@ -80,6 +75,6 @@ class ProviderAccountViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class ProviderNetworkViewSet(NetBoxModelViewSet):
|
||||
queryset = ProviderNetwork.objects.prefetch_related('tags')
|
||||
queryset = ProviderNetwork.objects.all()
|
||||
serializer_class = serializers.ProviderNetworkSerializer
|
||||
filterset_class = filtersets.ProviderNetworkFilterSet
|
||||
|
@ -44,7 +44,7 @@ class DataSourceViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class DataFileViewSet(NetBoxReadOnlyModelViewSet):
|
||||
queryset = DataFile.objects.defer('data').prefetch_related('source')
|
||||
queryset = DataFile.objects.defer('data')
|
||||
serializer_class = serializers.DataFileSerializer
|
||||
filterset_class = filtersets.DataFileFilterSet
|
||||
|
||||
@ -53,6 +53,6 @@ class JobViewSet(ReadOnlyModelViewSet):
|
||||
"""
|
||||
Retrieve a list of job results
|
||||
"""
|
||||
queryset = Job.objects.prefetch_related('user')
|
||||
queryset = Job.objects.all()
|
||||
serializer_class = serializers.JobSerializer
|
||||
filterset_class = filtersets.JobFilterSet
|
||||
|
@ -103,7 +103,7 @@ class RegionViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
'region',
|
||||
'site_count',
|
||||
cumulative=True
|
||||
).prefetch_related('tags')
|
||||
)
|
||||
serializer_class = serializers.RegionSerializer
|
||||
filterset_class = filtersets.RegionFilterSet
|
||||
|
||||
@ -119,7 +119,7 @@ class SiteGroupViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
'group',
|
||||
'site_count',
|
||||
cumulative=True
|
||||
).prefetch_related('tags')
|
||||
)
|
||||
serializer_class = serializers.SiteGroupSerializer
|
||||
filterset_class = filtersets.SiteGroupFilterSet
|
||||
|
||||
@ -129,9 +129,7 @@ class SiteGroupViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class SiteViewSet(NetBoxModelViewSet):
|
||||
queryset = Site.objects.prefetch_related(
|
||||
'region', 'tenant', 'asns', 'tags'
|
||||
).annotate(
|
||||
queryset = Site.objects.annotate(
|
||||
device_count=count_related(Device, 'site'),
|
||||
rack_count=count_related(Rack, 'site'),
|
||||
prefix_count=count_related(Prefix, 'site'),
|
||||
@ -160,7 +158,7 @@ class LocationViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
'location',
|
||||
'rack_count',
|
||||
cumulative=True
|
||||
).prefetch_related('site', 'tags')
|
||||
)
|
||||
serializer_class = serializers.LocationSerializer
|
||||
filterset_class = filtersets.LocationFilterSet
|
||||
|
||||
@ -170,7 +168,7 @@ class LocationViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class RackRoleViewSet(NetBoxModelViewSet):
|
||||
queryset = RackRole.objects.prefetch_related('tags').annotate(
|
||||
queryset = RackRole.objects.annotate(
|
||||
rack_count=count_related(Rack, 'role')
|
||||
)
|
||||
serializer_class = serializers.RackRoleSerializer
|
||||
@ -182,9 +180,7 @@ class RackRoleViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class RackViewSet(NetBoxModelViewSet):
|
||||
queryset = Rack.objects.prefetch_related(
|
||||
'site', 'location', 'role', 'tenant', 'tags'
|
||||
).annotate(
|
||||
queryset = Rack.objects.annotate(
|
||||
device_count=count_related(Device, 'rack'),
|
||||
powerfeed_count=count_related(PowerFeed, 'rack')
|
||||
)
|
||||
@ -249,7 +245,7 @@ class RackViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class RackReservationViewSet(NetBoxModelViewSet):
|
||||
queryset = RackReservation.objects.prefetch_related('rack', 'user', 'tenant')
|
||||
queryset = RackReservation.objects.all()
|
||||
serializer_class = serializers.RackReservationSerializer
|
||||
filterset_class = filtersets.RackReservationFilterSet
|
||||
|
||||
@ -259,7 +255,7 @@ class RackReservationViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class ManufacturerViewSet(NetBoxModelViewSet):
|
||||
queryset = Manufacturer.objects.prefetch_related('tags').annotate(
|
||||
queryset = Manufacturer.objects.annotate(
|
||||
devicetype_count=count_related(DeviceType, 'manufacturer'),
|
||||
inventoryitem_count=count_related(InventoryItem, 'manufacturer'),
|
||||
platform_count=count_related(Platform, 'manufacturer')
|
||||
@ -273,21 +269,17 @@ class ManufacturerViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class DeviceTypeViewSet(NetBoxModelViewSet):
|
||||
queryset = DeviceType.objects.prefetch_related('manufacturer', 'default_platform', 'tags').annotate(
|
||||
queryset = DeviceType.objects.annotate(
|
||||
device_count=count_related(Device, 'device_type')
|
||||
)
|
||||
serializer_class = serializers.DeviceTypeSerializer
|
||||
filterset_class = filtersets.DeviceTypeFilterSet
|
||||
brief_prefetch_fields = ['manufacturer']
|
||||
|
||||
|
||||
class ModuleTypeViewSet(NetBoxModelViewSet):
|
||||
queryset = ModuleType.objects.prefetch_related('manufacturer', 'tags').annotate(
|
||||
# module_count=count_related(Module, 'module_type')
|
||||
)
|
||||
queryset = ModuleType.objects.all()
|
||||
serializer_class = serializers.ModuleTypeSerializer
|
||||
filterset_class = filtersets.ModuleTypeFilterSet
|
||||
brief_prefetch_fields = ['manufacturer']
|
||||
|
||||
|
||||
#
|
||||
@ -295,61 +287,61 @@ class ModuleTypeViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class ConsolePortTemplateViewSet(NetBoxModelViewSet):
|
||||
queryset = ConsolePortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
queryset = ConsolePortTemplate.objects.all()
|
||||
serializer_class = serializers.ConsolePortTemplateSerializer
|
||||
filterset_class = filtersets.ConsolePortTemplateFilterSet
|
||||
|
||||
|
||||
class ConsoleServerPortTemplateViewSet(NetBoxModelViewSet):
|
||||
queryset = ConsoleServerPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
queryset = ConsoleServerPortTemplate.objects.all()
|
||||
serializer_class = serializers.ConsoleServerPortTemplateSerializer
|
||||
filterset_class = filtersets.ConsoleServerPortTemplateFilterSet
|
||||
|
||||
|
||||
class PowerPortTemplateViewSet(NetBoxModelViewSet):
|
||||
queryset = PowerPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
queryset = PowerPortTemplate.objects.all()
|
||||
serializer_class = serializers.PowerPortTemplateSerializer
|
||||
filterset_class = filtersets.PowerPortTemplateFilterSet
|
||||
|
||||
|
||||
class PowerOutletTemplateViewSet(NetBoxModelViewSet):
|
||||
queryset = PowerOutletTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
queryset = PowerOutletTemplate.objects.all()
|
||||
serializer_class = serializers.PowerOutletTemplateSerializer
|
||||
filterset_class = filtersets.PowerOutletTemplateFilterSet
|
||||
|
||||
|
||||
class InterfaceTemplateViewSet(NetBoxModelViewSet):
|
||||
queryset = InterfaceTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
queryset = InterfaceTemplate.objects.all()
|
||||
serializer_class = serializers.InterfaceTemplateSerializer
|
||||
filterset_class = filtersets.InterfaceTemplateFilterSet
|
||||
|
||||
|
||||
class FrontPortTemplateViewSet(NetBoxModelViewSet):
|
||||
queryset = FrontPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
queryset = FrontPortTemplate.objects.all()
|
||||
serializer_class = serializers.FrontPortTemplateSerializer
|
||||
filterset_class = filtersets.FrontPortTemplateFilterSet
|
||||
|
||||
|
||||
class RearPortTemplateViewSet(NetBoxModelViewSet):
|
||||
queryset = RearPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
queryset = RearPortTemplate.objects.all()
|
||||
serializer_class = serializers.RearPortTemplateSerializer
|
||||
filterset_class = filtersets.RearPortTemplateFilterSet
|
||||
|
||||
|
||||
class ModuleBayTemplateViewSet(NetBoxModelViewSet):
|
||||
queryset = ModuleBayTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
queryset = ModuleBayTemplate.objects.all()
|
||||
serializer_class = serializers.ModuleBayTemplateSerializer
|
||||
filterset_class = filtersets.ModuleBayTemplateFilterSet
|
||||
|
||||
|
||||
class DeviceBayTemplateViewSet(NetBoxModelViewSet):
|
||||
queryset = DeviceBayTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
queryset = DeviceBayTemplate.objects.all()
|
||||
serializer_class = serializers.DeviceBayTemplateSerializer
|
||||
filterset_class = filtersets.DeviceBayTemplateFilterSet
|
||||
|
||||
|
||||
class InventoryItemTemplateViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
queryset = InventoryItemTemplate.objects.prefetch_related('device_type__manufacturer', 'role')
|
||||
queryset = InventoryItemTemplate.objects.all()
|
||||
serializer_class = serializers.InventoryItemTemplateSerializer
|
||||
filterset_class = filtersets.InventoryItemTemplateFilterSet
|
||||
|
||||
@ -359,7 +351,7 @@ class InventoryItemTemplateViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class DeviceRoleViewSet(NetBoxModelViewSet):
|
||||
queryset = DeviceRole.objects.prefetch_related('config_template', 'tags').annotate(
|
||||
queryset = DeviceRole.objects.annotate(
|
||||
device_count=count_related(Device, 'role'),
|
||||
virtualmachine_count=count_related(VirtualMachine, 'role')
|
||||
)
|
||||
@ -372,7 +364,7 @@ class DeviceRoleViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class PlatformViewSet(NetBoxModelViewSet):
|
||||
queryset = Platform.objects.prefetch_related('config_template', 'tags').annotate(
|
||||
queryset = Platform.objects.annotate(
|
||||
device_count=count_related(Device, 'platform'),
|
||||
virtualmachine_count=count_related(VirtualMachine, 'platform')
|
||||
)
|
||||
@ -391,8 +383,7 @@ class DeviceViewSet(
|
||||
NetBoxModelViewSet
|
||||
):
|
||||
queryset = Device.objects.prefetch_related(
|
||||
'device_type__manufacturer', 'role', 'tenant', 'platform', 'site', 'location', 'rack', 'parent_bay',
|
||||
'virtual_chassis__master', 'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'config_template', 'tags',
|
||||
'parent_bay', # Referenced by DeviceSerializer.get_parent_device()
|
||||
)
|
||||
filterset_class = filtersets.DeviceFilterSet
|
||||
pagination_class = StripCountAnnotationsPaginator
|
||||
@ -419,9 +410,7 @@ class DeviceViewSet(
|
||||
|
||||
|
||||
class VirtualDeviceContextViewSet(NetBoxModelViewSet):
|
||||
queryset = VirtualDeviceContext.objects.prefetch_related(
|
||||
'device__device_type', 'device', 'tenant', 'tags',
|
||||
).annotate(
|
||||
queryset = VirtualDeviceContext.objects.annotate(
|
||||
interface_count=count_related(Interface, 'vdcs'),
|
||||
)
|
||||
serializer_class = serializers.VirtualDeviceContextSerializer
|
||||
@ -429,9 +418,7 @@ class VirtualDeviceContextViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class ModuleViewSet(NetBoxModelViewSet):
|
||||
queryset = Module.objects.prefetch_related(
|
||||
'device', 'module_bay', 'module_type__manufacturer', 'tags',
|
||||
)
|
||||
queryset = Module.objects.all()
|
||||
serializer_class = serializers.ModuleSerializer
|
||||
filterset_class = filtersets.ModuleFilterSet
|
||||
|
||||
@ -442,49 +429,45 @@ class ModuleViewSet(NetBoxModelViewSet):
|
||||
|
||||
class ConsolePortViewSet(PathEndpointMixin, NetBoxModelViewSet):
|
||||
queryset = ConsolePort.objects.prefetch_related(
|
||||
'device', 'module__module_bay', '_path', 'cable__terminations', 'tags'
|
||||
'_path', 'cable__terminations',
|
||||
)
|
||||
serializer_class = serializers.ConsolePortSerializer
|
||||
filterset_class = filtersets.ConsolePortFilterSet
|
||||
brief_prefetch_fields = ['device']
|
||||
|
||||
|
||||
class ConsoleServerPortViewSet(PathEndpointMixin, NetBoxModelViewSet):
|
||||
queryset = ConsoleServerPort.objects.prefetch_related(
|
||||
'device', 'module__module_bay', '_path', 'cable__terminations', 'tags'
|
||||
'_path', 'cable__terminations',
|
||||
)
|
||||
serializer_class = serializers.ConsoleServerPortSerializer
|
||||
filterset_class = filtersets.ConsoleServerPortFilterSet
|
||||
brief_prefetch_fields = ['device']
|
||||
|
||||
|
||||
class PowerPortViewSet(PathEndpointMixin, NetBoxModelViewSet):
|
||||
queryset = PowerPort.objects.prefetch_related(
|
||||
'device', 'module__module_bay', '_path', 'cable__terminations', 'tags'
|
||||
'_path', 'cable__terminations',
|
||||
)
|
||||
serializer_class = serializers.PowerPortSerializer
|
||||
filterset_class = filtersets.PowerPortFilterSet
|
||||
brief_prefetch_fields = ['device']
|
||||
|
||||
|
||||
class PowerOutletViewSet(PathEndpointMixin, NetBoxModelViewSet):
|
||||
queryset = PowerOutlet.objects.prefetch_related(
|
||||
'device', 'module__module_bay', '_path', 'cable__terminations', 'tags'
|
||||
'_path', 'cable__terminations',
|
||||
)
|
||||
serializer_class = serializers.PowerOutletSerializer
|
||||
filterset_class = filtersets.PowerOutletFilterSet
|
||||
brief_prefetch_fields = ['device']
|
||||
|
||||
|
||||
class InterfaceViewSet(PathEndpointMixin, NetBoxModelViewSet):
|
||||
queryset = Interface.objects.prefetch_related(
|
||||
'device', 'module__module_bay', 'parent', 'bridge', 'lag', '_path', 'cable__terminations', 'wireless_lans',
|
||||
'untagged_vlan', 'tagged_vlans', 'vrf', 'ip_addresses', 'fhrp_group_assignments', 'tags', 'l2vpn_terminations',
|
||||
'vdcs',
|
||||
'_path', 'cable__terminations',
|
||||
'l2vpn_terminations', # Referenced by InterfaceSerializer.l2vpn_termination
|
||||
'ip_addresses', # Referenced by Interface.count_ipaddresses()
|
||||
'fhrp_group_assignments', # Referenced by Interface.count_fhrp_groups()
|
||||
)
|
||||
serializer_class = serializers.InterfaceSerializer
|
||||
filterset_class = filtersets.InterfaceFilterSet
|
||||
brief_prefetch_fields = ['device']
|
||||
|
||||
def get_bulk_destroy_queryset(self):
|
||||
# Ensure child interfaces are deleted prior to their parents
|
||||
@ -493,41 +476,36 @@ class InterfaceViewSet(PathEndpointMixin, NetBoxModelViewSet):
|
||||
|
||||
class FrontPortViewSet(PassThroughPortMixin, NetBoxModelViewSet):
|
||||
queryset = FrontPort.objects.prefetch_related(
|
||||
'device__device_type__manufacturer', 'module__module_bay', 'rear_port', 'cable__terminations', 'tags'
|
||||
'cable__terminations',
|
||||
)
|
||||
serializer_class = serializers.FrontPortSerializer
|
||||
filterset_class = filtersets.FrontPortFilterSet
|
||||
brief_prefetch_fields = ['device']
|
||||
|
||||
|
||||
class RearPortViewSet(PassThroughPortMixin, NetBoxModelViewSet):
|
||||
queryset = RearPort.objects.prefetch_related(
|
||||
'device__device_type__manufacturer', 'module__module_bay', 'cable__terminations', 'tags'
|
||||
'cable__terminations',
|
||||
)
|
||||
serializer_class = serializers.RearPortSerializer
|
||||
filterset_class = filtersets.RearPortFilterSet
|
||||
brief_prefetch_fields = ['device']
|
||||
|
||||
|
||||
class ModuleBayViewSet(NetBoxModelViewSet):
|
||||
queryset = ModuleBay.objects.prefetch_related('tags', 'installed_module')
|
||||
queryset = ModuleBay.objects.all()
|
||||
serializer_class = serializers.ModuleBaySerializer
|
||||
filterset_class = filtersets.ModuleBayFilterSet
|
||||
brief_prefetch_fields = ['device']
|
||||
|
||||
|
||||
class DeviceBayViewSet(NetBoxModelViewSet):
|
||||
queryset = DeviceBay.objects.prefetch_related('installed_device', 'tags')
|
||||
queryset = DeviceBay.objects.all()
|
||||
serializer_class = serializers.DeviceBaySerializer
|
||||
filterset_class = filtersets.DeviceBayFilterSet
|
||||
brief_prefetch_fields = ['device']
|
||||
|
||||
|
||||
class InventoryItemViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer', 'tags')
|
||||
queryset = InventoryItem.objects.all()
|
||||
serializer_class = serializers.InventoryItemSerializer
|
||||
filterset_class = filtersets.InventoryItemFilterSet
|
||||
brief_prefetch_fields = ['device']
|
||||
|
||||
|
||||
#
|
||||
@ -535,7 +513,7 @@ class InventoryItemViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class InventoryItemRoleViewSet(NetBoxModelViewSet):
|
||||
queryset = InventoryItemRole.objects.prefetch_related('tags').annotate(
|
||||
queryset = InventoryItemRole.objects.annotate(
|
||||
inventoryitem_count=count_related(InventoryItem, 'role')
|
||||
)
|
||||
serializer_class = serializers.InventoryItemRoleSerializer
|
||||
@ -554,7 +532,7 @@ class CableViewSet(NetBoxModelViewSet):
|
||||
|
||||
class CableTerminationViewSet(NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = CableTermination.objects.prefetch_related('cable', 'termination')
|
||||
queryset = CableTermination.objects.all()
|
||||
serializer_class = serializers.CableTerminationSerializer
|
||||
filterset_class = filtersets.CableTerminationFilterSet
|
||||
|
||||
@ -564,10 +542,9 @@ class CableTerminationViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class VirtualChassisViewSet(NetBoxModelViewSet):
|
||||
queryset = VirtualChassis.objects.prefetch_related('tags')
|
||||
queryset = VirtualChassis.objects.all()
|
||||
serializer_class = serializers.VirtualChassisSerializer
|
||||
filterset_class = filtersets.VirtualChassisFilterSet
|
||||
brief_prefetch_fields = ['master']
|
||||
|
||||
|
||||
#
|
||||
@ -575,9 +552,7 @@ class VirtualChassisViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class PowerPanelViewSet(NetBoxModelViewSet):
|
||||
queryset = PowerPanel.objects.prefetch_related(
|
||||
'site', 'location'
|
||||
).annotate(
|
||||
queryset = PowerPanel.objects.annotate(
|
||||
powerfeed_count=count_related(PowerFeed, 'power_panel')
|
||||
)
|
||||
serializer_class = serializers.PowerPanelSerializer
|
||||
@ -590,7 +565,7 @@ class PowerPanelViewSet(NetBoxModelViewSet):
|
||||
|
||||
class PowerFeedViewSet(PathEndpointMixin, NetBoxModelViewSet):
|
||||
queryset = PowerFeed.objects.prefetch_related(
|
||||
'power_panel', 'rack', '_path', 'cable__terminations', 'tags'
|
||||
'_path', 'cable__terminations',
|
||||
)
|
||||
serializer_class = serializers.PowerFeedSerializer
|
||||
filterset_class = filtersets.PowerFeedFilterSet
|
||||
|
@ -115,7 +115,7 @@ class CustomLinkViewSet(NetBoxModelViewSet):
|
||||
|
||||
class ExportTemplateViewSet(SyncedDataMixin, NetBoxModelViewSet):
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = ExportTemplate.objects.prefetch_related('data_source', 'data_file')
|
||||
queryset = ExportTemplate.objects.all()
|
||||
serializer_class = serializers.ExportTemplateSerializer
|
||||
filterset_class = filtersets.ExportTemplateFilterSet
|
||||
|
||||
@ -181,10 +181,7 @@ class JournalEntryViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class ConfigContextViewSet(SyncedDataMixin, NetBoxModelViewSet):
|
||||
queryset = ConfigContext.objects.prefetch_related(
|
||||
'regions', 'site_groups', 'sites', 'locations', 'roles', 'platforms', 'tenant_groups', 'tenants', 'data_source',
|
||||
'data_file',
|
||||
)
|
||||
queryset = ConfigContext.objects.all()
|
||||
serializer_class = serializers.ConfigContextSerializer
|
||||
filterset_class = filtersets.ConfigContextFilterSet
|
||||
|
||||
@ -194,7 +191,7 @@ class ConfigContextViewSet(SyncedDataMixin, NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class ConfigTemplateViewSet(SyncedDataMixin, ConfigTemplateRenderMixin, NetBoxModelViewSet):
|
||||
queryset = ConfigTemplate.objects.prefetch_related('data_source', 'data_file')
|
||||
queryset = ConfigTemplate.objects.all()
|
||||
serializer_class = serializers.ConfigTemplateSerializer
|
||||
filterset_class = filtersets.ConfigTemplateFilterSet
|
||||
|
||||
@ -312,7 +309,7 @@ class ObjectChangeViewSet(ReadOnlyModelViewSet):
|
||||
Retrieve a list of recent changes.
|
||||
"""
|
||||
metadata_class = ContentTypeMetadata
|
||||
queryset = ObjectChange.objects.valid_models().prefetch_related('user')
|
||||
queryset = ObjectChange.objects.valid_models()
|
||||
serializer_class = serializers.ObjectChangeSerializer
|
||||
filterset_class = filtersets.ObjectChangeFilterSet
|
||||
|
||||
|
@ -116,10 +116,11 @@ class NestedFHRPGroupSerializer(WritableNestedSerializer):
|
||||
|
||||
class NestedFHRPGroupAssignmentSerializer(WritableNestedSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:fhrpgroupassignment-detail')
|
||||
group = NestedFHRPGroupSerializer()
|
||||
|
||||
class Meta:
|
||||
model = models.FHRPGroupAssignment
|
||||
fields = ['id', 'url', 'display', 'interface_type', 'interface_id', 'group_id', 'priority']
|
||||
fields = ['id', 'url', 'display', 'group', 'interface_type', 'interface_id', 'priority']
|
||||
|
||||
|
||||
#
|
||||
|
@ -39,13 +39,13 @@ class IPAMRootView(APIRootView):
|
||||
#
|
||||
|
||||
class ASNRangeViewSet(NetBoxModelViewSet):
|
||||
queryset = ASNRange.objects.prefetch_related('tenant', 'rir').all()
|
||||
queryset = ASNRange.objects.all()
|
||||
serializer_class = serializers.ASNRangeSerializer
|
||||
filterset_class = filtersets.ASNRangeFilterSet
|
||||
|
||||
|
||||
class ASNViewSet(NetBoxModelViewSet):
|
||||
queryset = ASN.objects.prefetch_related('tenant', 'rir').annotate(
|
||||
queryset = ASN.objects.annotate(
|
||||
site_count=count_related(Site, 'asns'),
|
||||
provider_count=count_related(Provider, 'asns')
|
||||
)
|
||||
@ -54,9 +54,7 @@ class ASNViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class VRFViewSet(NetBoxModelViewSet):
|
||||
queryset = VRF.objects.prefetch_related('tenant').prefetch_related(
|
||||
'import_targets', 'export_targets', 'tags'
|
||||
).annotate(
|
||||
queryset = VRF.objects.annotate(
|
||||
ipaddress_count=count_related(IPAddress, 'vrf'),
|
||||
prefix_count=count_related(Prefix, 'vrf')
|
||||
)
|
||||
@ -65,7 +63,7 @@ class VRFViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class RouteTargetViewSet(NetBoxModelViewSet):
|
||||
queryset = RouteTarget.objects.prefetch_related('tenant').prefetch_related('tags')
|
||||
queryset = RouteTarget.objects.all()
|
||||
serializer_class = serializers.RouteTargetSerializer
|
||||
filterset_class = filtersets.RouteTargetFilterSet
|
||||
|
||||
@ -73,13 +71,13 @@ class RouteTargetViewSet(NetBoxModelViewSet):
|
||||
class RIRViewSet(NetBoxModelViewSet):
|
||||
queryset = RIR.objects.annotate(
|
||||
aggregate_count=count_related(Aggregate, 'rir')
|
||||
).prefetch_related('tags')
|
||||
)
|
||||
serializer_class = serializers.RIRSerializer
|
||||
filterset_class = filtersets.RIRFilterSet
|
||||
|
||||
|
||||
class AggregateViewSet(NetBoxModelViewSet):
|
||||
queryset = Aggregate.objects.prefetch_related('rir').prefetch_related('tags')
|
||||
queryset = Aggregate.objects.all()
|
||||
serializer_class = serializers.AggregateSerializer
|
||||
filterset_class = filtersets.AggregateFilterSet
|
||||
|
||||
@ -88,15 +86,13 @@ class RoleViewSet(NetBoxModelViewSet):
|
||||
queryset = Role.objects.annotate(
|
||||
prefix_count=count_related(Prefix, 'role'),
|
||||
vlan_count=count_related(VLAN, 'role')
|
||||
).prefetch_related('tags')
|
||||
)
|
||||
serializer_class = serializers.RoleSerializer
|
||||
filterset_class = filtersets.RoleFilterSet
|
||||
|
||||
|
||||
class PrefixViewSet(NetBoxModelViewSet):
|
||||
queryset = Prefix.objects.prefetch_related(
|
||||
'site', 'vrf__tenant', 'tenant', 'vlan', 'role', 'tags'
|
||||
)
|
||||
queryset = Prefix.objects.all()
|
||||
serializer_class = serializers.PrefixSerializer
|
||||
filterset_class = filtersets.PrefixFilterSet
|
||||
|
||||
@ -109,7 +105,7 @@ class PrefixViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class IPRangeViewSet(NetBoxModelViewSet):
|
||||
queryset = IPRange.objects.prefetch_related('vrf', 'role', 'tenant', 'tags')
|
||||
queryset = IPRange.objects.all()
|
||||
serializer_class = serializers.IPRangeSerializer
|
||||
filterset_class = filtersets.IPRangeFilterSet
|
||||
|
||||
@ -117,9 +113,7 @@ class IPRangeViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class IPAddressViewSet(NetBoxModelViewSet):
|
||||
queryset = IPAddress.objects.prefetch_related(
|
||||
'vrf__tenant', 'tenant', 'nat_inside', 'nat_outside', 'tags', 'assigned_object'
|
||||
)
|
||||
queryset = IPAddress.objects.all()
|
||||
serializer_class = serializers.IPAddressSerializer
|
||||
filterset_class = filtersets.IPAddressFilterSet
|
||||
|
||||
@ -137,27 +131,26 @@ class IPAddressViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class FHRPGroupViewSet(NetBoxModelViewSet):
|
||||
queryset = FHRPGroup.objects.prefetch_related('ip_addresses', 'tags')
|
||||
queryset = FHRPGroup.objects.all()
|
||||
serializer_class = serializers.FHRPGroupSerializer
|
||||
filterset_class = filtersets.FHRPGroupFilterSet
|
||||
brief_prefetch_fields = ('ip_addresses',)
|
||||
|
||||
|
||||
class FHRPGroupAssignmentViewSet(NetBoxModelViewSet):
|
||||
queryset = FHRPGroupAssignment.objects.prefetch_related('group', 'interface')
|
||||
queryset = FHRPGroupAssignment.objects.all()
|
||||
serializer_class = serializers.FHRPGroupAssignmentSerializer
|
||||
filterset_class = filtersets.FHRPGroupAssignmentFilterSet
|
||||
|
||||
|
||||
class VLANGroupViewSet(NetBoxModelViewSet):
|
||||
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
|
||||
queryset = VLANGroup.objects.annotate_utilization()
|
||||
serializer_class = serializers.VLANGroupSerializer
|
||||
filterset_class = filtersets.VLANGroupFilterSet
|
||||
|
||||
|
||||
class VLANViewSet(NetBoxModelViewSet):
|
||||
queryset = VLAN.objects.prefetch_related(
|
||||
'site', 'group', 'tenant', 'role', 'tags'
|
||||
'l2vpn_terminations', # Referenced by VLANSerializer.l2vpn_termination
|
||||
).annotate(
|
||||
prefix_count=count_related(Prefix, 'vlan')
|
||||
)
|
||||
@ -166,15 +159,13 @@ class VLANViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class ServiceTemplateViewSet(NetBoxModelViewSet):
|
||||
queryset = ServiceTemplate.objects.prefetch_related('tags')
|
||||
queryset = ServiceTemplate.objects.all()
|
||||
serializer_class = serializers.ServiceTemplateSerializer
|
||||
filterset_class = filtersets.ServiceTemplateFilterSet
|
||||
|
||||
|
||||
class ServiceViewSet(NetBoxModelViewSet):
|
||||
queryset = Service.objects.prefetch_related(
|
||||
'device', 'virtual_machine', 'tags', 'ipaddresses'
|
||||
)
|
||||
queryset = Service.objects.all()
|
||||
serializer_class = serializers.ServiceSerializer
|
||||
filterset_class = filtersets.ServiceFilterSet
|
||||
|
||||
|
@ -760,7 +760,7 @@ class FHRPGroupTest(APIViewTestCases.APIViewTestCase):
|
||||
|
||||
class FHRPGroupAssignmentTest(APIViewTestCases.APIViewTestCase):
|
||||
model = FHRPGroupAssignment
|
||||
brief_fields = ['display', 'group_id', 'id', 'interface_id', 'interface_type', 'priority', 'url']
|
||||
brief_fields = ['display', 'group', 'id', 'interface_id', 'interface_type', 'priority', 'url']
|
||||
bulk_update_data = {
|
||||
'priority': 100,
|
||||
}
|
||||
|
@ -12,6 +12,15 @@ __all__ = (
|
||||
class BaseModelSerializer(serializers.ModelSerializer):
|
||||
display = serializers.SerializerMethodField(read_only=True)
|
||||
|
||||
def __init__(self, *args, requested_fields=None, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# If specific fields have been requested, omit the others
|
||||
if requested_fields:
|
||||
for field in list(self.fields.keys()):
|
||||
if field not in requested_fields:
|
||||
self.fields.pop(field)
|
||||
|
||||
@extend_schema_field(OpenApiTypes.STR)
|
||||
def get_display(self, obj):
|
||||
return str(obj)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import logging
|
||||
from functools import cached_property
|
||||
|
||||
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
||||
from django.db import transaction
|
||||
@ -9,6 +10,7 @@ from rest_framework import mixins as drf_mixins
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import GenericViewSet
|
||||
|
||||
from utilities.api import get_prefetches_for_serializer
|
||||
from utilities.exceptions import AbortRequest
|
||||
from . import mixins
|
||||
|
||||
@ -40,6 +42,32 @@ class BaseViewSet(GenericViewSet):
|
||||
if action := HTTP_ACTIONS[request.method]:
|
||||
self.queryset = self.queryset.restrict(request.user, action)
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super().get_queryset()
|
||||
|
||||
# Dynamically resolve prefetches for included serializer fields and attach them to the queryset
|
||||
prefetch = get_prefetches_for_serializer(
|
||||
self.get_serializer_class(),
|
||||
fields_to_include=self.requested_fields
|
||||
)
|
||||
if prefetch:
|
||||
qs = qs.prefetch_related(*prefetch)
|
||||
|
||||
return qs
|
||||
|
||||
def get_serializer(self, *args, **kwargs):
|
||||
|
||||
# If specific fields have been requested, pass them to the serializer
|
||||
if self.requested_fields:
|
||||
kwargs['requested_fields'] = self.requested_fields
|
||||
|
||||
return super().get_serializer(*args, **kwargs)
|
||||
|
||||
@cached_property
|
||||
def requested_fields(self):
|
||||
requested_fields = self.request.query_params.get('fields')
|
||||
return requested_fields.split(',') if requested_fields else []
|
||||
|
||||
|
||||
class NetBoxReadOnlyModelViewSet(
|
||||
mixins.BriefModeMixin,
|
||||
|
@ -30,7 +30,6 @@ class BriefModeMixin:
|
||||
GET /api/dcim/sites/?brief=True
|
||||
"""
|
||||
brief = False
|
||||
brief_prefetch_fields = []
|
||||
|
||||
def initialize_request(self, request, *args, **kwargs):
|
||||
# Annotate whether brief mode is active
|
||||
@ -64,9 +63,6 @@ class BriefModeMixin:
|
||||
if annotation not in serializer_class().fields:
|
||||
qs.query.annotations.pop(annotation)
|
||||
|
||||
# Clear any prefetches from the queryset and append only brief_prefetch_fields (if any)
|
||||
return qs.prefetch_related(None).prefetch_related(*self.brief_prefetch_fields)
|
||||
|
||||
return qs
|
||||
|
||||
|
||||
|
@ -30,15 +30,13 @@ class TenantGroupViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
'group',
|
||||
'tenant_count',
|
||||
cumulative=True
|
||||
).prefetch_related('tags')
|
||||
)
|
||||
serializer_class = serializers.TenantGroupSerializer
|
||||
filterset_class = filtersets.TenantGroupFilterSet
|
||||
|
||||
|
||||
class TenantViewSet(NetBoxModelViewSet):
|
||||
queryset = Tenant.objects.prefetch_related(
|
||||
'group', 'tags'
|
||||
).annotate(
|
||||
queryset = Tenant.objects.annotate(
|
||||
circuit_count=count_related(Circuit, 'tenant'),
|
||||
device_count=count_related(Device, 'tenant'),
|
||||
ipaddress_count=count_related(IPAddress, 'tenant'),
|
||||
@ -65,24 +63,24 @@ class ContactGroupViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
'group',
|
||||
'contact_count',
|
||||
cumulative=True
|
||||
).prefetch_related('tags')
|
||||
)
|
||||
serializer_class = serializers.ContactGroupSerializer
|
||||
filterset_class = filtersets.ContactGroupFilterSet
|
||||
|
||||
|
||||
class ContactRoleViewSet(NetBoxModelViewSet):
|
||||
queryset = ContactRole.objects.prefetch_related('tags')
|
||||
queryset = ContactRole.objects.all()
|
||||
serializer_class = serializers.ContactRoleSerializer
|
||||
filterset_class = filtersets.ContactRoleFilterSet
|
||||
|
||||
|
||||
class ContactViewSet(NetBoxModelViewSet):
|
||||
queryset = Contact.objects.prefetch_related('group', 'tags')
|
||||
queryset = Contact.objects.all()
|
||||
serializer_class = serializers.ContactSerializer
|
||||
filterset_class = filtersets.ContactFilterSet
|
||||
|
||||
|
||||
class ContactAssignmentViewSet(NetBoxModelViewSet):
|
||||
queryset = ContactAssignment.objects.prefetch_related('content_type', 'object', 'contact', 'role', 'tags')
|
||||
queryset = ContactAssignment.objects.all()
|
||||
serializer_class = serializers.ContactAssignmentSerializer
|
||||
filterset_class = filtersets.ContactAssignmentFilterSet
|
||||
|
@ -34,7 +34,7 @@ class UsersRootView(APIRootView):
|
||||
#
|
||||
|
||||
class UserViewSet(NetBoxModelViewSet):
|
||||
queryset = RestrictedQuerySet(model=get_user_model()).prefetch_related('groups').order_by('username')
|
||||
queryset = RestrictedQuerySet(model=get_user_model()).order_by('username')
|
||||
serializer_class = serializers.UserSerializer
|
||||
filterset_class = filtersets.UserFilterSet
|
||||
|
||||
@ -50,7 +50,7 @@ class GroupViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class TokenViewSet(NetBoxModelViewSet):
|
||||
queryset = Token.objects.prefetch_related('user')
|
||||
queryset = Token.objects.all()
|
||||
serializer_class = serializers.TokenSerializer
|
||||
filterset_class = filtersets.TokenFilterSet
|
||||
|
||||
@ -86,7 +86,7 @@ class TokenProvisionView(APIView):
|
||||
#
|
||||
|
||||
class ObjectPermissionViewSet(NetBoxModelViewSet):
|
||||
queryset = ObjectPermission.objects.prefetch_related('object_types', 'groups', 'users')
|
||||
queryset = ObjectPermission.objects.all()
|
||||
serializer_class = serializers.ObjectPermissionSerializer
|
||||
filterset_class = filtersets.ObjectPermissionFilterSet
|
||||
|
||||
|
@ -2,9 +2,13 @@ import platform
|
||||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||
from django.core.exceptions import FieldDoesNotExist
|
||||
from django.db.models.fields.related import ManyToOneRel, RelatedField
|
||||
from django.http import JsonResponse
|
||||
from django.urls import reverse
|
||||
from rest_framework import status
|
||||
from rest_framework.serializers import Serializer
|
||||
from rest_framework.utils import formatting
|
||||
|
||||
from netbox.api.exceptions import GraphQLTypeNotFound, SerializerNotFound
|
||||
@ -12,6 +16,7 @@ from .utils import dynamic_import
|
||||
|
||||
__all__ = (
|
||||
'get_graphql_type_for_model',
|
||||
'get_prefetches_for_serializer',
|
||||
'get_serializer_for_model',
|
||||
'get_view_name',
|
||||
'is_api_request',
|
||||
@ -89,6 +94,43 @@ def get_view_name(view, suffix=None):
|
||||
return name
|
||||
|
||||
|
||||
def get_prefetches_for_serializer(serializer_class, fields_to_include=None):
|
||||
"""
|
||||
Compile and return a list of fields which should be prefetched on the queryset for a serializer.
|
||||
"""
|
||||
model = serializer_class.Meta.model
|
||||
|
||||
# If specific fields are not specified, default to all
|
||||
if not fields_to_include:
|
||||
fields_to_include = serializer_class.Meta.fields
|
||||
|
||||
prefetch_fields = []
|
||||
for field_name in fields_to_include:
|
||||
serializer_field = serializer_class._declared_fields.get(field_name)
|
||||
|
||||
# Determine the name of the model field referenced by the serializer field
|
||||
model_field_name = field_name
|
||||
if serializer_field and serializer_field.source:
|
||||
model_field_name = serializer_field.source
|
||||
|
||||
# If the serializer field does not map to a discrete model field, skip it.
|
||||
try:
|
||||
field = model._meta.get_field(model_field_name)
|
||||
if isinstance(field, (RelatedField, ManyToOneRel, GenericForeignKey)):
|
||||
prefetch_fields.append(field.name)
|
||||
except FieldDoesNotExist:
|
||||
continue
|
||||
|
||||
# If this field is represented by a nested serializer, recurse to resolve prefetches
|
||||
# for the related object.
|
||||
if serializer_field:
|
||||
if issubclass(type(serializer_field), Serializer):
|
||||
for subfield in get_prefetches_for_serializer(type(serializer_field)):
|
||||
prefetch_fields.append(f'{field_name}__{subfield}')
|
||||
|
||||
return prefetch_fields
|
||||
|
||||
|
||||
def rest_api_server_error(request, *args, **kwargs):
|
||||
"""
|
||||
Handle exceptions and return a useful error message for REST API requests.
|
||||
|
@ -25,7 +25,7 @@ class VirtualizationRootView(APIRootView):
|
||||
class ClusterTypeViewSet(NetBoxModelViewSet):
|
||||
queryset = ClusterType.objects.annotate(
|
||||
cluster_count=count_related(Cluster, 'type')
|
||||
).prefetch_related('tags')
|
||||
)
|
||||
serializer_class = serializers.ClusterTypeSerializer
|
||||
filterset_class = filtersets.ClusterTypeFilterSet
|
||||
|
||||
@ -33,15 +33,13 @@ class ClusterTypeViewSet(NetBoxModelViewSet):
|
||||
class ClusterGroupViewSet(NetBoxModelViewSet):
|
||||
queryset = ClusterGroup.objects.annotate(
|
||||
cluster_count=count_related(Cluster, 'group')
|
||||
).prefetch_related('tags')
|
||||
)
|
||||
serializer_class = serializers.ClusterGroupSerializer
|
||||
filterset_class = filtersets.ClusterGroupFilterSet
|
||||
|
||||
|
||||
class ClusterViewSet(NetBoxModelViewSet):
|
||||
queryset = Cluster.objects.prefetch_related(
|
||||
'type', 'group', 'tenant', 'site', 'tags'
|
||||
).annotate(
|
||||
queryset = Cluster.objects.annotate(
|
||||
device_count=count_related(Device, 'cluster'),
|
||||
virtualmachine_count=count_related(VirtualMachine, 'cluster')
|
||||
)
|
||||
@ -54,10 +52,7 @@ class ClusterViewSet(NetBoxModelViewSet):
|
||||
#
|
||||
|
||||
class VirtualMachineViewSet(ConfigContextQuerySetMixin, RenderConfigMixin, NetBoxModelViewSet):
|
||||
queryset = VirtualMachine.objects.prefetch_related(
|
||||
'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'primary_ip4', 'primary_ip6', 'config_template',
|
||||
'tags', 'virtualdisks',
|
||||
)
|
||||
queryset = VirtualMachine.objects.all()
|
||||
filterset_class = filtersets.VirtualMachineFilterSet
|
||||
|
||||
def get_serializer_class(self):
|
||||
@ -83,12 +78,12 @@ class VirtualMachineViewSet(ConfigContextQuerySetMixin, RenderConfigMixin, NetBo
|
||||
|
||||
class VMInterfaceViewSet(NetBoxModelViewSet):
|
||||
queryset = VMInterface.objects.prefetch_related(
|
||||
'virtual_machine', 'parent', 'tags', 'untagged_vlan', 'tagged_vlans', 'vrf', 'ip_addresses',
|
||||
'fhrp_group_assignments',
|
||||
'l2vpn_terminations', # Referenced by VMInterfaceSerializer.l2vpn_termination
|
||||
'ip_addresses', # Referenced by VMInterface.count_ipaddresses()
|
||||
'fhrp_group_assignments', # Referenced by VMInterface.count_fhrp_groups()
|
||||
)
|
||||
serializer_class = serializers.VMInterfaceSerializer
|
||||
filterset_class = filtersets.VMInterfaceFilterSet
|
||||
brief_prefetch_fields = ['virtual_machine']
|
||||
|
||||
def get_bulk_destroy_queryset(self):
|
||||
# Ensure child interfaces are deleted prior to their parents
|
||||
@ -96,9 +91,6 @@ class VMInterfaceViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class VirtualDiskViewSet(NetBoxModelViewSet):
|
||||
queryset = VirtualDisk.objects.prefetch_related(
|
||||
'virtual_machine', 'tags',
|
||||
)
|
||||
queryset = VirtualDisk.objects.all()
|
||||
serializer_class = serializers.VirtualDiskSerializer
|
||||
filterset_class = filtersets.VirtualDiskFilterSet
|
||||
brief_prefetch_fields = ['virtual_machine']
|
||||
|
@ -42,7 +42,7 @@ class TunnelGroupViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class TunnelViewSet(NetBoxModelViewSet):
|
||||
queryset = Tunnel.objects.prefetch_related('ipsec_profile', 'tenant').annotate(
|
||||
queryset = Tunnel.objects.annotate(
|
||||
terminations_count=count_related(TunnelTermination, 'tunnel')
|
||||
)
|
||||
serializer_class = serializers.TunnelSerializer
|
||||
@ -50,7 +50,7 @@ class TunnelViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class TunnelTerminationViewSet(NetBoxModelViewSet):
|
||||
queryset = TunnelTermination.objects.prefetch_related('tunnel')
|
||||
queryset = TunnelTermination.objects.all()
|
||||
serializer_class = serializers.TunnelTerminationSerializer
|
||||
filterset_class = filtersets.TunnelTerminationFilterSet
|
||||
|
||||
@ -86,12 +86,12 @@ class IPSecProfileViewSet(NetBoxModelViewSet):
|
||||
|
||||
|
||||
class L2VPNViewSet(NetBoxModelViewSet):
|
||||
queryset = L2VPN.objects.prefetch_related('import_targets', 'export_targets', 'tenant', 'tags')
|
||||
queryset = L2VPN.objects.all()
|
||||
serializer_class = serializers.L2VPNSerializer
|
||||
filterset_class = filtersets.L2VPNFilterSet
|
||||
|
||||
|
||||
class L2VPNTerminationViewSet(NetBoxModelViewSet):
|
||||
queryset = L2VPNTermination.objects.prefetch_related('assigned_object')
|
||||
queryset = L2VPNTermination.objects.all()
|
||||
serializer_class = serializers.L2VPNTerminationSerializer
|
||||
filterset_class = filtersets.L2VPNTerminationFilterSet
|
||||
|
@ -27,12 +27,12 @@ class WirelessLANGroupViewSet(MPTTLockedMixin, NetBoxModelViewSet):
|
||||
|
||||
|
||||
class WirelessLANViewSet(NetBoxModelViewSet):
|
||||
queryset = WirelessLAN.objects.prefetch_related('vlan', 'tenant', 'tags')
|
||||
queryset = WirelessLAN.objects.all()
|
||||
serializer_class = serializers.WirelessLANSerializer
|
||||
filterset_class = filtersets.WirelessLANFilterSet
|
||||
|
||||
|
||||
class WirelessLinkViewSet(NetBoxModelViewSet):
|
||||
queryset = WirelessLink.objects.prefetch_related('interface_a', 'interface_b', 'tenant', 'tags')
|
||||
queryset = WirelessLink.objects.all()
|
||||
serializer_class = serializers.WirelessLinkSerializer
|
||||
filterset_class = filtersets.WirelessLinkFilterSet
|
||||
|
Reference in New Issue
Block a user