1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #15235: Use primary serializers for REST API "brief" mode (#15246)

* Use primary serializers for brief mode

* Remove BriefModeMixin

* Correct ModuleBayTest brief_fields (see #15243)
This commit is contained in:
Jeremy Stretch
2024-02-23 14:21:25 -05:00
committed by GitHub
parent ca2ee436a0
commit 3f3bcc5eb5
13 changed files with 129 additions and 44 deletions

View File

@ -40,6 +40,7 @@ class ProviderSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'accounts', 'description', 'comments', 'asns', 'tags',
'custom_fields', 'created', 'last_updated', 'circuit_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'circuit_count')
#
@ -56,6 +57,7 @@ class ProviderAccountSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'provider', 'name', 'account', 'description', 'comments', 'tags', 'custom_fields',
'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'account')
#
@ -72,6 +74,7 @@ class ProviderNetworkSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'provider', 'name', 'service_id', 'description', 'comments', 'tags',
'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
#
@ -90,6 +93,7 @@ class CircuitTypeSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'color', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'circuit_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'circuit_count')
class CircuitCircuitTerminationSerializer(WritableNestedSerializer):
@ -122,6 +126,7 @@ class CircuitSerializer(NetBoxModelSerializer):
'termination_date', 'commit_rate', 'description', 'termination_a', 'termination_z', 'comments', 'tags',
'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'cid')
class CircuitTerminationSerializer(NetBoxModelSerializer, CabledObjectSerializer):
@ -137,3 +142,4 @@ class CircuitTerminationSerializer(NetBoxModelSerializer, CabledObjectSerializer
'xconnect_id', 'pp_info', 'description', 'mark_connected', 'cable', 'cable_end', 'link_peers',
'link_peers_type', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
]
brief_fields = ('id', 'url', 'display', 'circuit', 'term_side', 'cable', '_occupied')

View File

@ -36,6 +36,7 @@ class DataSourceSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'type', 'source_url', 'enabled', 'status', 'description', 'comments',
'parameters', 'ignore_rules', 'custom_fields', 'created', 'last_updated', 'file_count',
]
brief_fields = ('id', 'url', 'display', 'name')
class DataFileSerializer(NetBoxModelSerializer):
@ -51,6 +52,7 @@ class DataFileSerializer(NetBoxModelSerializer):
fields = [
'id', 'url', 'display', 'source', 'path', 'last_updated', 'size', 'hash',
]
brief_fields = ('id', 'url', 'display', 'path')
class JobSerializer(BaseModelSerializer):
@ -69,3 +71,4 @@ class JobSerializer(BaseModelSerializer):
'id', 'url', 'display', 'object_type', 'object_id', 'name', 'status', 'created', 'scheduled', 'interval',
'started', 'completed', 'user', 'data', 'error', 'job_id',
]
brief_fields = ('url', 'created', 'completed', 'user', 'status')

View File

@ -114,6 +114,7 @@ class RegionSerializer(NestedGroupModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'parent', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'site_count', '_depth',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'site_count', '_depth')
class SiteGroupSerializer(NestedGroupModelSerializer):
@ -127,6 +128,7 @@ class SiteGroupSerializer(NestedGroupModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'parent', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'site_count', '_depth',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'site_count', '_depth')
class SiteSerializer(NetBoxModelSerializer):
@ -159,6 +161,7 @@ class SiteSerializer(NetBoxModelSerializer):
'custom_fields', 'created', 'last_updated', 'circuit_count', 'device_count', 'prefix_count', 'rack_count',
'virtualmachine_count', 'vlan_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug')
#
@ -180,6 +183,7 @@ class LocationSerializer(NestedGroupModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'site', 'parent', 'status', 'tenant', 'description', 'tags',
'custom_fields', 'created', 'last_updated', 'rack_count', 'device_count', '_depth',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'rack_count', '_depth')
class RackRoleSerializer(NetBoxModelSerializer):
@ -194,6 +198,7 @@ class RackRoleSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'color', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'rack_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'rack_count')
class RackSerializer(NetBoxModelSerializer):
@ -222,6 +227,7 @@ class RackSerializer(NetBoxModelSerializer):
'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'description', 'comments',
'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'powerfeed_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'device_count')
class RackUnitSerializer(serializers.Serializer):
@ -256,6 +262,7 @@ class RackReservationSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'rack', 'units', 'created', 'last_updated', 'user', 'tenant', 'description',
'comments', 'tags', 'custom_fields',
]
brief_fields = ('id', 'url', 'display', 'user', 'units')
class RackElevationDetailFilterSerializer(serializers.Serializer):
@ -315,6 +322,7 @@ class ManufacturerSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'description', 'tags', 'custom_fields', 'created', 'last_updated',
'devicetype_count', 'inventoryitem_count', 'platform_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'devicetype_count')
class DeviceTypeSerializer(NetBoxModelSerializer):
@ -360,6 +368,7 @@ class DeviceTypeSerializer(NetBoxModelSerializer):
'rear_port_template_count', 'device_bay_template_count', 'module_bay_template_count',
'inventory_item_template_count',
]
brief_fields = ('id', 'url', 'display', 'manufacturer', 'model', 'slug', 'device_count')
class ModuleTypeSerializer(NetBoxModelSerializer):
@ -373,6 +382,7 @@ class ModuleTypeSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'description',
'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'manufacturer', 'model')
#
@ -403,6 +413,7 @@ class ConsolePortTemplateSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'description', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
@ -429,6 +440,7 @@ class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'description', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
class PowerPortTemplateSerializer(ValidatedModelSerializer):
@ -456,6 +468,7 @@ class PowerPortTemplateSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'maximum_draw',
'allocated_draw', 'description', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
class PowerOutletTemplateSerializer(ValidatedModelSerializer):
@ -493,6 +506,7 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'power_port', 'feed_leg',
'description', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
class InterfaceTemplateSerializer(ValidatedModelSerializer):
@ -537,6 +551,7 @@ class InterfaceTemplateSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only',
'description', 'bridge', 'poe_mode', 'poe_type', 'rf_role', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
class RearPortTemplateSerializer(ValidatedModelSerializer):
@ -559,6 +574,7 @@ class RearPortTemplateSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'color', 'positions',
'description', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
class FrontPortTemplateSerializer(ValidatedModelSerializer):
@ -582,6 +598,7 @@ class FrontPortTemplateSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'color', 'rear_port',
'rear_port_position', 'description', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
class ModuleBayTemplateSerializer(ValidatedModelSerializer):
@ -594,6 +611,7 @@ class ModuleBayTemplateSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'device_type', 'name', 'label', 'position', 'description', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
class DeviceBayTemplateSerializer(ValidatedModelSerializer):
@ -603,6 +621,7 @@ class DeviceBayTemplateSerializer(ValidatedModelSerializer):
class Meta:
model = DeviceBayTemplate
fields = ['id', 'url', 'display', 'device_type', 'name', 'label', 'description', 'created', 'last_updated']
brief_fields = ('id', 'url', 'display', 'name')
class InventoryItemTemplateSerializer(ValidatedModelSerializer):
@ -629,6 +648,7 @@ class InventoryItemTemplateSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'device_type', 'parent', 'name', 'label', 'role', 'manufacturer', 'part_id',
'description', 'component_type', 'component_id', 'component', 'created', 'last_updated', '_depth',
]
brief_fields = ('id', 'url', 'display', 'name', '_depth')
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_component(self, obj):
@ -657,6 +677,7 @@ class DeviceRoleSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'color', 'vm_role', 'config_template', 'description', 'tags',
'custom_fields', 'created', 'last_updated', 'device_count', 'virtualmachine_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'device_count', 'virtualmachine_count')
class PlatformSerializer(NetBoxModelSerializer):
@ -674,6 +695,7 @@ class PlatformSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'manufacturer', 'config_template', 'description', 'tags',
'custom_fields', 'created', 'last_updated', 'device_count', 'virtualmachine_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'device_count', 'virtualmachine_count')
class DeviceSerializer(NetBoxModelSerializer):
@ -730,6 +752,7 @@ class DeviceSerializer(NetBoxModelSerializer):
'power_port_count', 'power_outlet_count', 'interface_count', 'front_port_count', 'rear_port_count',
'device_bay_count', 'module_bay_count', 'inventory_item_count',
]
brief_fields = ('id', 'url', 'display', 'name')
@extend_schema_field(NestedDeviceSerializer)
def get_parent_device(self, obj):
@ -784,6 +807,7 @@ class VirtualDeviceContextSerializer(NetBoxModelSerializer):
'primary_ip6', 'status', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
'interface_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'identifier', 'device')
class ModuleSerializer(NetBoxModelSerializer):
@ -799,6 +823,7 @@ class ModuleSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'device', 'module_bay', 'module_type', 'status', 'serial', 'asset_tag',
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'device', 'module_bay', 'module_type')
#
@ -831,6 +856,7 @@ class ConsoleServerPortSerializer(NetBoxModelSerializer, CabledObjectSerializer,
'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields', 'created',
'last_updated', '_occupied',
]
brief_fields = ('id', 'url', 'display', 'device', 'name', 'cable', '_occupied')
class ConsolePortSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
@ -859,6 +885,7 @@ class ConsolePortSerializer(NetBoxModelSerializer, CabledObjectSerializer, Conne
'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields', 'created',
'last_updated', '_occupied',
]
brief_fields = ('id', 'url', 'display', 'device', 'name', 'cable', '_occupied')
class PowerOutletSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
@ -893,6 +920,7 @@ class PowerOutletSerializer(NetBoxModelSerializer, CabledObjectSerializer, Conne
'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields',
'created', 'last_updated', '_occupied',
]
brief_fields = ('id', 'url', 'display', 'device', 'name', 'cable', '_occupied')
class PowerPortSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
@ -917,6 +945,7 @@ class PowerPortSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields',
'created', 'last_updated', '_occupied',
]
brief_fields = ('id', 'url', 'display', 'device', 'name', 'cable', '_occupied')
class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
@ -979,6 +1008,7 @@ class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields', 'created',
'last_updated', 'count_ipaddresses', 'count_fhrp_groups', '_occupied',
]
brief_fields = ('id', 'url', 'display', 'device', 'name', 'cable', '_occupied')
def validate(self, data):
@ -1010,6 +1040,7 @@ class RearPortSerializer(NetBoxModelSerializer, CabledObjectSerializer):
'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type', 'tags', 'custom_fields', 'created',
'last_updated', '_occupied',
]
brief_fields = ('id', 'url', 'display', 'device', 'name', 'cable', '_occupied')
class FrontPortRearPortSerializer(WritableNestedSerializer):
@ -1040,6 +1071,7 @@ class FrontPortSerializer(NetBoxModelSerializer, CabledObjectSerializer):
'rear_port_position', 'description', 'mark_connected', 'cable', 'cable_end', 'link_peers',
'link_peers_type', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
]
brief_fields = ('id', 'url', 'display', 'device', 'name', 'cable', '_occupied')
class ModuleBaySerializer(NetBoxModelSerializer):
@ -1051,9 +1083,9 @@ class ModuleBaySerializer(NetBoxModelSerializer):
model = ModuleBay
fields = [
'id', 'url', 'display', 'device', 'name', 'installed_module', 'label', 'position', 'description', 'tags',
'custom_fields',
'created', 'last_updated',
'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'installed_module', 'name')
class DeviceBaySerializer(NetBoxModelSerializer):
@ -1067,6 +1099,7 @@ class DeviceBaySerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'device', 'name', 'label', 'description', 'installed_device', 'tags',
'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'device', 'name')
class InventoryItemSerializer(NetBoxModelSerializer):
@ -1090,6 +1123,7 @@ class InventoryItemSerializer(NetBoxModelSerializer):
'asset_tag', 'discovered', 'description', 'component_type', 'component_id', 'component', 'tags',
'custom_fields', 'created', 'last_updated', '_depth',
]
brief_fields = ('id', 'url', 'display', 'device', 'name', '_depth')
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_component(self, obj):
@ -1116,6 +1150,7 @@ class InventoryItemRoleSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'color', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'inventoryitem_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'inventoryitem_count')
#
@ -1136,6 +1171,7 @@ class CableSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'type', 'a_terminations', 'b_terminations', 'status', 'tenant', 'label', 'color',
'length', 'length_unit', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'label')
class TracedCableSerializer(serializers.ModelSerializer):
@ -1206,6 +1242,7 @@ class VirtualChassisSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'domain', 'master', 'description', 'comments', 'tags', 'custom_fields',
'created', 'last_updated', 'member_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'master', 'member_count')
#
@ -1230,6 +1267,7 @@ class PowerPanelSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'site', 'location', 'name', 'description', 'comments', 'tags', 'custom_fields',
'powerfeed_count', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'powerfeed_count')
class PowerFeedSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
@ -1269,3 +1307,4 @@ class PowerFeedSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect
'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable', 'description',
'tenant', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
]
brief_fields = ('id', 'url', 'display', 'name', 'cable', '_occupied')

View File

@ -1755,7 +1755,7 @@ class RearPortTest(APIViewTestCases.APIViewTestCase):
class ModuleBayTest(APIViewTestCases.APIViewTestCase):
model = ModuleBay
brief_fields = ['display', 'id', 'module', 'name', 'url']
brief_fields = ['display', 'id', 'installed_module', 'name', 'url']
bulk_update_data = {
'description': 'New description',
}

View File

@ -76,6 +76,7 @@ class EventRuleSerializer(NetBoxModelSerializer):
'type_job_start', 'type_job_end', 'enabled', 'conditions', 'action_type', 'action_object_type',
'action_object_id', 'action_object', 'description', 'custom_fields', 'tags', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
@extend_schema_field(OpenApiTypes.OBJECT)
def get_action_object(self, instance):
@ -107,6 +108,7 @@ class WebhookSerializer(NetBoxModelSerializer):
'additional_headers', 'body_template', 'secret', 'ssl_verification', 'ca_file_path', 'custom_fields',
'tags', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
#
@ -142,6 +144,7 @@ class CustomFieldSerializer(ValidatedModelSerializer):
'default', 'weight', 'validation_minimum', 'validation_maximum', 'validation_regex', 'choice_set',
'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
def validate_type(self, value):
if self.instance and self.instance.type != value:
@ -184,6 +187,7 @@ class CustomFieldChoiceSetSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'name', 'description', 'base_choices', 'extra_choices', 'order_alphabetically',
'choices_count', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'choices_count')
#
@ -203,6 +207,7 @@ class CustomLinkSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'content_types', 'name', 'enabled', 'link_text', 'link_url', 'weight', 'group_name',
'button_class', 'new_window', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
#
@ -229,6 +234,7 @@ class ExportTemplateSerializer(ValidatedModelSerializer):
'file_extension', 'as_attachment', 'data_source', 'data_path', 'data_file', 'data_synced', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
#
@ -248,6 +254,7 @@ class SavedFilterSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'content_types', 'name', 'slug', 'description', 'user', 'weight', 'enabled',
'shared', 'parameters', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug')
#
@ -267,6 +274,7 @@ class BookmarkSerializer(ValidatedModelSerializer):
fields = [
'id', 'url', 'display', 'object_type', 'object_id', 'object', 'user', 'created',
]
brief_fields = ('id', 'url', 'display', 'object_id', 'object_type')
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_object(self, instance):
@ -295,6 +303,7 @@ class TagSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'color', 'description', 'object_types', 'tagged_items', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'color')
#
@ -314,6 +323,7 @@ class ImageAttachmentSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'content_type', 'object_id', 'parent', 'name', 'image', 'image_height',
'image_width', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'image')
def validate(self, data):
@ -363,6 +373,7 @@ class JournalEntrySerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'assigned_object_type', 'assigned_object_id', 'assigned_object', 'created',
'created_by', 'kind', 'comments', 'tags', 'custom_fields', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'created')
def validate(self, data):
@ -486,6 +497,7 @@ class ConfigContextSerializer(ValidatedModelSerializer):
'tenant_groups', 'tenants', 'tags', 'data_source', 'data_path', 'data_file', 'data_synced', 'data',
'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
#
@ -507,6 +519,7 @@ class ConfigTemplateSerializer(TaggableModelSerializer, ValidatedModelSerializer
'id', 'url', 'display', 'name', 'description', 'environment_params', 'template_code', 'data_source',
'data_path', 'data_file', 'data_synced', 'tags', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
#
@ -524,6 +537,7 @@ class ScriptSerializer(ValidatedModelSerializer):
fields = [
'id', 'url', 'module', 'name', 'description', 'vars', 'result', 'display', 'is_executable',
]
brief_fields = ('id', 'url', 'display', 'name')
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_vars(self, obj):

View File

@ -33,6 +33,7 @@ class ASNRangeSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'rir', 'start', 'end', 'tenant', 'description', 'tags',
'custom_fields', 'created', 'last_updated', 'asn_count',
]
brief_fields = ('id', 'url', 'display', 'name')
#
@ -54,6 +55,7 @@ class ASNSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'asn', 'rir', 'tenant', 'description', 'comments', 'tags', 'custom_fields',
'created', 'last_updated', 'site_count', 'provider_count',
]
brief_fields = ('id', 'url', 'display', 'asn')
class AvailableASNSerializer(serializers.Serializer):
@ -104,6 +106,7 @@ class VRFSerializer(NetBoxModelSerializer):
'import_targets', 'export_targets', 'tags', 'custom_fields', 'created', 'last_updated', 'ipaddress_count',
'prefix_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'rd', 'prefix_count')
#
@ -120,6 +123,7 @@ class RouteTargetSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'tenant', 'description', 'comments', 'tags', 'custom_fields', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
#
@ -138,6 +142,7 @@ class RIRSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'is_private', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'aggregate_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'aggregate_count')
class AggregateSerializer(NetBoxModelSerializer):
@ -153,6 +158,7 @@ class AggregateSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'family', 'prefix', 'rir', 'tenant', 'date_added', 'description', 'comments',
'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'family', 'prefix')
#
@ -169,6 +175,7 @@ class FHRPGroupSerializer(NetBoxModelSerializer):
'id', 'name', 'url', 'display', 'protocol', 'group_id', 'auth_type', 'auth_key', 'description', 'comments',
'tags', 'custom_fields', 'created', 'last_updated', 'ip_addresses',
]
brief_fields = ('id', 'url', 'display', 'protocol', 'group_id')
class FHRPGroupAssignmentSerializer(NetBoxModelSerializer):
@ -185,6 +192,7 @@ class FHRPGroupAssignmentSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'group', 'interface_type', 'interface_id', 'interface', 'priority', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'group', 'interface_type', 'interface_id', 'priority')
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_interface(self, obj):
@ -212,6 +220,7 @@ class RoleSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'weight', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'prefix_count', 'vlan_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'prefix_count', 'vlan_count')
class VLANGroupSerializer(NetBoxModelSerializer):
@ -237,6 +246,7 @@ class VLANGroupSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'scope_type', 'scope_id', 'scope', 'min_vid', 'max_vid',
'description', 'tags', 'custom_fields', 'created', 'last_updated', 'vlan_count', 'utilization'
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'vlan_count')
validators = []
@extend_schema_field(serializers.JSONField(allow_null=True))
@ -267,6 +277,7 @@ class VLANSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description',
'comments', 'l2vpn_termination', 'tags', 'custom_fields', 'created', 'last_updated', 'prefix_count',
]
brief_fields = ('id', 'url', 'display', 'vid', 'name')
class AvailableVLANSerializer(serializers.Serializer):
@ -327,6 +338,7 @@ class PrefixSerializer(NetBoxModelSerializer):
'mark_utilized', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'children',
'_depth',
]
brief_fields = ('id', 'url', 'display', 'family', 'prefix', '_depth')
class PrefixLengthSerializer(serializers.Serializer):
@ -397,6 +409,7 @@ class IPRangeSerializer(NetBoxModelSerializer):
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
'mark_utilized', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'family', 'start_address', 'end_address')
#
@ -427,6 +440,7 @@ class IPAddressSerializer(NetBoxModelSerializer):
'assigned_object_id', 'assigned_object', 'nat_inside', 'nat_outside', 'dns_name', 'description', 'comments',
'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'family', 'address')
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_assigned_object(self, obj):
@ -472,6 +486,7 @@ class ServiceTemplateSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'ports', 'protocol', 'description', 'comments', 'tags', 'custom_fields',
'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'protocol', 'ports')
class ServiceSerializer(NetBoxModelSerializer):
@ -492,3 +507,4 @@ class ServiceSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'device', 'virtual_machine', 'name', 'ports', 'protocol', 'ipaddresses',
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'protocol', 'ports')

View File

@ -34,6 +34,8 @@ class BaseViewSet(GenericViewSet):
"""
Base class for all API ViewSets. This is responsible for the enforcement of object-based permissions.
"""
brief = False
def initial(self, request, *args, **kwargs):
super().initial(request, *args, **kwargs)
@ -42,6 +44,13 @@ class BaseViewSet(GenericViewSet):
if action := HTTP_ACTIONS[request.method]:
self.queryset = self.queryset.restrict(request.user, action)
def initialize_request(self, request, *args, **kwargs):
# Annotate whether brief mode is active
self.brief = request.method == 'GET' and request.GET.get('brief')
return super().initialize_request(request, *args, **kwargs)
def get_queryset(self):
qs = super().get_queryset()
serializer_class = self.get_serializer_class()
@ -66,12 +75,17 @@ class BaseViewSet(GenericViewSet):
@cached_property
def requested_fields(self):
requested_fields = self.request.query_params.get('fields')
return requested_fields.split(',') if requested_fields else []
# An explicit list of fields was requested
if requested_fields := self.request.query_params.get('fields'):
return requested_fields.split(',')
# Brief mode has been enabled for this request
elif self.brief:
serializer_class = self.get_serializer_class()
return getattr(serializer_class.Meta, 'brief_fields', None)
return None
class NetBoxReadOnlyModelViewSet(
mixins.BriefModeMixin,
mixins.CustomFieldsMixin,
mixins.ExportTemplatesMixin,
drf_mixins.RetrieveModelMixin,
@ -85,7 +99,6 @@ class NetBoxModelViewSet(
mixins.BulkUpdateModelMixin,
mixins.BulkDestroyModelMixin,
mixins.ObjectValidationMixin,
mixins.BriefModeMixin,
mixins.CustomFieldsMixin,
mixins.ExportTemplatesMixin,
drf_mixins.CreateModelMixin,

View File

@ -1,5 +1,3 @@
import logging
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
@ -8,13 +6,9 @@ from rest_framework import status
from rest_framework.response import Response
from extras.models import ExportTemplate
from netbox.api.exceptions import SerializerNotFound
from netbox.api.serializers import BulkOperationSerializer
from netbox.constants import NESTED_SERIALIZER_PREFIX
from utilities.api import get_serializer_for_model
__all__ = (
'BriefModeMixin',
'BulkDestroyModelMixin',
'BulkUpdateModelMixin',
'CustomFieldsMixin',
@ -24,35 +18,6 @@ __all__ = (
)
class BriefModeMixin:
"""
Enables brief mode support, so that the client can invoke a model's nested serializer by passing e.g.
GET /api/dcim/sites/?brief=True
"""
brief = False
def initialize_request(self, request, *args, **kwargs):
# Annotate whether brief mode is active
self.brief = request.method == 'GET' and request.GET.get('brief')
return super().initialize_request(request, *args, **kwargs)
def get_serializer_class(self):
logger = logging.getLogger(f'netbox.api.views.{self.__class__.__name__}')
# If using 'brief' mode, find and return the nested serializer for this model, if one exists
if self.brief:
logger.debug("Request is for 'brief' format; initializing nested serializer")
try:
return get_serializer_for_model(self.queryset.model, prefix=NESTED_SERIALIZER_PREFIX)
except SerializerNotFound:
logger.debug(
f"Nested serializer for {self.queryset.model} not found! Using serializer {self.serializer_class}"
)
return self.serializer_class
class CustomFieldsMixin:
"""
For models which support custom fields, populate the `custom_fields` context.

View File

@ -27,6 +27,7 @@ class TenantGroupSerializer(NestedGroupModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'parent', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'tenant_count', '_depth',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'tenant_count', '_depth')
class TenantSerializer(NetBoxModelSerializer):
@ -52,6 +53,7 @@ class TenantSerializer(NetBoxModelSerializer):
'created', 'last_updated', 'circuit_count', 'device_count', 'ipaddress_count', 'prefix_count', 'rack_count',
'site_count', 'virtualmachine_count', 'vlan_count', 'vrf_count', 'cluster_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug')
#
@ -69,6 +71,7 @@ class ContactGroupSerializer(NestedGroupModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'parent', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'contact_count', '_depth',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'contact_count', '_depth')
class ContactRoleSerializer(NetBoxModelSerializer):
@ -79,6 +82,7 @@ class ContactRoleSerializer(NetBoxModelSerializer):
fields = [
'id', 'url', 'display', 'name', 'slug', 'description', 'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug')
class ContactSerializer(NetBoxModelSerializer):
@ -91,6 +95,7 @@ class ContactSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description',
'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name')
class ContactAssignmentSerializer(NetBoxModelSerializer):
@ -109,6 +114,7 @@ class ContactAssignmentSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'content_type', 'object_id', 'object', 'contact', 'role', 'priority', 'tags',
'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'contact', 'role', 'priority')
@extend_schema_field(OpenApiTypes.OBJECT)
def get_object(self, instance):

View File

@ -37,6 +37,7 @@ class UserSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'username', 'password', 'first_name', 'last_name', 'email', 'is_staff', 'is_active',
'date_joined', 'last_login', 'groups',
)
brief_fields = ('id', 'url', 'display', 'username')
extra_kwargs = {
'password': {'write_only': True}
}
@ -76,6 +77,7 @@ class GroupSerializer(ValidatedModelSerializer):
class Meta:
model = Group
fields = ('id', 'url', 'display', 'name', 'user_count')
brief_fields = ('id', 'url', 'display', 'name')
class TokenSerializer(ValidatedModelSerializer):
@ -101,6 +103,7 @@ class TokenSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'user', 'created', 'expires', 'last_used', 'key', 'write_enabled', 'description',
'allowed_ips',
)
brief_fields = ('id', 'url', 'display', 'key', 'write_enabled')
def to_internal_value(self, data):
if 'key' not in data:
@ -181,3 +184,4 @@ class ObjectPermissionSerializer(ValidatedModelSerializer):
'id', 'url', 'display', 'name', 'description', 'enabled', 'object_types', 'groups', 'users', 'actions',
'constraints',
)
brief_fields = ('id', 'url', 'display', 'name', 'enabled', 'object_types', 'groups', 'users', 'actions')

View File

@ -33,6 +33,7 @@ class ClusterTypeSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'description', 'tags', 'custom_fields', 'created', 'last_updated',
'cluster_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'cluster_count')
class ClusterGroupSerializer(NetBoxModelSerializer):
@ -47,6 +48,7 @@ class ClusterGroupSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'description', 'tags', 'custom_fields', 'created', 'last_updated',
'cluster_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'cluster_count')
class ClusterSerializer(NetBoxModelSerializer):
@ -67,6 +69,7 @@ class ClusterSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'type', 'group', 'status', 'tenant', 'site', 'description', 'comments',
'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'virtualmachine_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'virtualmachine_count')
#
@ -99,6 +102,7 @@ class VirtualMachineSerializer(NetBoxModelSerializer):
'config_template', 'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
'interface_count', 'virtual_disk_count',
]
brief_fields = ('id', 'url', 'display', 'name')
validators = []
@ -152,6 +156,7 @@ class VMInterfaceSerializer(NetBoxModelSerializer):
'description', 'mode', 'untagged_vlan', 'tagged_vlans', 'vrf', 'l2vpn_termination', 'tags', 'custom_fields',
'created', 'last_updated', 'count_ipaddresses', 'count_fhrp_groups',
]
brief_fields = ('id', 'url', 'display', 'virtual_machine', 'name')
def validate(self, data):
@ -178,6 +183,7 @@ class VirtualDiskSerializer(NetBoxModelSerializer):
class Meta:
model = VirtualDisk
fields = [
'id', 'url', 'virtual_machine', 'name', 'description', 'size', 'tags', 'custom_fields', 'created',
'last_updated',
'id', 'url', 'display', 'virtual_machine', 'name', 'description', 'size', 'tags', 'custom_fields',
'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'virtual_machine', 'name', 'size')

View File

@ -39,6 +39,7 @@ class TunnelGroupSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'description', 'tags', 'custom_fields', 'created', 'last_updated',
'tunnel_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'tunnel_count')
class TunnelSerializer(NetBoxModelSerializer):
@ -73,6 +74,7 @@ class TunnelSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'status', 'group', 'encapsulation', 'ipsec_profile', 'tenant', 'tunnel_id',
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'terminations_count',
)
brief_fields = ('id', 'url', 'display', 'name')
class TunnelTerminationSerializer(NetBoxModelSerializer):
@ -100,6 +102,7 @@ class TunnelTerminationSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'tunnel', 'role', 'termination_type', 'termination_id', 'termination', 'outside_ip',
'tags', 'custom_fields', 'created', 'last_updated',
)
brief_fields = ('id', 'url', 'display')
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_termination(self, obj):
@ -132,6 +135,7 @@ class IKEProposalSerializer(NetBoxModelSerializer):
'authentication_algorithm', 'group', 'sa_lifetime', 'comments', 'tags', 'custom_fields', 'created',
'last_updated',
)
brief_fields = ('id', 'url', 'display', 'name')
class IKEPolicySerializer(NetBoxModelSerializer):
@ -157,6 +161,7 @@ class IKEPolicySerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'description', 'version', 'mode', 'proposals', 'preshared_key', 'comments',
'tags', 'custom_fields', 'created', 'last_updated',
)
brief_fields = ('id', 'url', 'display', 'name')
class IPSecProposalSerializer(NetBoxModelSerializer):
@ -176,6 +181,7 @@ class IPSecProposalSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'description', 'encryption_algorithm', 'authentication_algorithm',
'sa_lifetime_seconds', 'sa_lifetime_data', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
)
brief_fields = ('id', 'url', 'display', 'name')
class IPSecPolicySerializer(NetBoxModelSerializer):
@ -199,6 +205,7 @@ class IPSecPolicySerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'description', 'proposals', 'pfs_group', 'comments', 'tags',
'custom_fields', 'created', 'last_updated',
)
brief_fields = ('id', 'url', 'display', 'name')
class IPSecProfileSerializer(NetBoxModelSerializer):
@ -217,6 +224,7 @@ class IPSecProfileSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'description', 'mode', 'ike_policy', 'ipsec_policy', 'comments', 'tags',
'custom_fields', 'created', 'last_updated',
)
brief_fields = ('id', 'url', 'display', 'name')
#
@ -246,6 +254,7 @@ class L2VPNSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'identifier', 'name', 'slug', 'type', 'import_targets', 'export_targets',
'description', 'comments', 'tenant', 'tags', 'custom_fields', 'created', 'last_updated'
]
brief_fields = ('id', 'url', 'display', 'identifier', 'name', 'slug', 'type')
class L2VPNTerminationSerializer(NetBoxModelSerializer):
@ -262,6 +271,7 @@ class L2VPNTerminationSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'l2vpn', 'assigned_object_type', 'assigned_object_id',
'assigned_object', 'tags', 'custom_fields', 'created', 'last_updated'
]
brief_fields = ('id', 'url', 'display', 'l2vpn')
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_assigned_object(self, instance):

View File

@ -28,6 +28,7 @@ class WirelessLANGroupSerializer(NestedGroupModelSerializer):
'id', 'url', 'display', 'name', 'slug', 'parent', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'wirelesslan_count', '_depth',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'wirelesslan_count', '_depth')
class WirelessLANSerializer(NetBoxModelSerializer):
@ -45,6 +46,7 @@ class WirelessLANSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'ssid', 'description', 'group', 'status', 'vlan', 'tenant', 'auth_type',
'auth_cipher', 'auth_psk', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'ssid')
class WirelessLinkSerializer(NetBoxModelSerializer):
@ -62,3 +64,4 @@ class WirelessLinkSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'interface_a', 'interface_b', 'ssid', 'status', 'tenant', 'auth_type',
'auth_cipher', 'auth_psk', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'ssid')