mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 17:38:37 -06:00
Change DeviceType export from CSV to YAML
This commit is contained in:
parent
473d67354f
commit
0dad9f8901
@ -2,6 +2,7 @@ from collections import OrderedDict
|
|||||||
from itertools import count, groupby
|
from itertools import count, groupby
|
||||||
|
|
||||||
import svgwrite
|
import svgwrite
|
||||||
|
import yaml
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
|
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
|
||||||
@ -25,15 +26,14 @@ from utilities.fields import ColorField
|
|||||||
from utilities.managers import NaturalOrderingManager
|
from utilities.managers import NaturalOrderingManager
|
||||||
from utilities.models import ChangeLoggedModel
|
from utilities.models import ChangeLoggedModel
|
||||||
from utilities.utils import foreground_color, to_meters
|
from utilities.utils import foreground_color, to_meters
|
||||||
from .device_components import (
|
|
||||||
CableTermination, ConsolePort, ConsoleServerPort, DeviceBay, FrontPort, Interface, InventoryItem, PowerOutlet,
|
|
||||||
PowerPort, RearPort,
|
|
||||||
)
|
|
||||||
from .device_component_templates import (
|
from .device_component_templates import (
|
||||||
ConsolePortTemplate, ConsoleServerPortTemplate, DeviceBayTemplate, FrontPortTemplate, InterfaceTemplate,
|
ConsolePortTemplate, ConsoleServerPortTemplate, DeviceBayTemplate, FrontPortTemplate, InterfaceTemplate,
|
||||||
PowerOutletTemplate, PowerPortTemplate, RearPortTemplate,
|
PowerOutletTemplate, PowerPortTemplate, RearPortTemplate,
|
||||||
)
|
)
|
||||||
|
from .device_components import (
|
||||||
|
CableTermination, ConsolePort, ConsoleServerPort, DeviceBay, FrontPort, Interface, InventoryItem, PowerOutlet,
|
||||||
|
PowerPort, RearPort,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'Cable',
|
'Cable',
|
||||||
@ -1003,17 +1003,92 @@ class DeviceType(ChangeLoggedModel, CustomFieldModel):
|
|||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('dcim:devicetype', args=[self.pk])
|
return reverse('dcim:devicetype', args=[self.pk])
|
||||||
|
|
||||||
def to_csv(self):
|
def to_yaml(self):
|
||||||
return (
|
data = OrderedDict((
|
||||||
self.manufacturer.name,
|
('manufacturer', self.manufacturer.name),
|
||||||
self.model,
|
('model', self.model),
|
||||||
self.slug,
|
('slug', self.slug),
|
||||||
self.part_number,
|
('part_number', self.part_number),
|
||||||
self.u_height,
|
('u_height', self.u_height),
|
||||||
self.is_full_depth,
|
('is_full_depth', self.is_full_depth),
|
||||||
self.get_subdevice_role_display(),
|
('subdevice_role', self.subdevice_role),
|
||||||
self.comments,
|
('comments', self.comments),
|
||||||
)
|
))
|
||||||
|
|
||||||
|
# Component templates
|
||||||
|
if self.consoleport_templates.exists():
|
||||||
|
data['console-ports'] = [
|
||||||
|
{
|
||||||
|
'name': c.name,
|
||||||
|
'type': c.type,
|
||||||
|
}
|
||||||
|
for c in self.consoleport_templates.all()
|
||||||
|
]
|
||||||
|
if self.consoleserverport_templates.exists():
|
||||||
|
data['console-server-ports'] = [
|
||||||
|
{
|
||||||
|
'name': c.name,
|
||||||
|
'type': c.type,
|
||||||
|
}
|
||||||
|
for c in self.consoleserverport_templates.all()
|
||||||
|
]
|
||||||
|
if self.powerport_templates.exists():
|
||||||
|
data['power-ports'] = [
|
||||||
|
{
|
||||||
|
'name': c.name,
|
||||||
|
'type': c.type,
|
||||||
|
'maximum_draw': c.maximum_draw,
|
||||||
|
'allocated_draw': c.allocated_draw,
|
||||||
|
}
|
||||||
|
for c in self.powerport_templates.all()
|
||||||
|
]
|
||||||
|
if self.poweroutlet_templates.exists():
|
||||||
|
data['power-outlets'] = [
|
||||||
|
{
|
||||||
|
'name': c.name,
|
||||||
|
'type': c.type,
|
||||||
|
'power_port': c.power_port.name if c.power_port else None,
|
||||||
|
'feed_leg': c.feed_leg,
|
||||||
|
}
|
||||||
|
for c in self.poweroutlet_templates.all()
|
||||||
|
]
|
||||||
|
if self.interface_templates.exists():
|
||||||
|
data['interfaces'] = [
|
||||||
|
{
|
||||||
|
'name': c.name,
|
||||||
|
'type': c.type,
|
||||||
|
'mgmt_only': c.mgmt_only,
|
||||||
|
}
|
||||||
|
for c in self.interface_templates.all()
|
||||||
|
]
|
||||||
|
if self.frontport_templates.exists():
|
||||||
|
data['front-ports'] = [
|
||||||
|
{
|
||||||
|
'name': c.name,
|
||||||
|
'type': c.type,
|
||||||
|
'rear_port': c.rear_port.name,
|
||||||
|
'rear_port_position': c.rear_port_position,
|
||||||
|
}
|
||||||
|
for c in self.frontport_templates.all()
|
||||||
|
]
|
||||||
|
if self.rearport_templates.exists():
|
||||||
|
data['rear-ports'] = [
|
||||||
|
{
|
||||||
|
'name': c.name,
|
||||||
|
'type': c.type,
|
||||||
|
'positions': c.positions,
|
||||||
|
}
|
||||||
|
for c in self.rearport_templates.all()
|
||||||
|
]
|
||||||
|
if self.device_bay_templates.exists():
|
||||||
|
data['device-bays'] = [
|
||||||
|
{
|
||||||
|
'name': c.name,
|
||||||
|
}
|
||||||
|
for c in self.device_bay_templates.all()
|
||||||
|
]
|
||||||
|
|
||||||
|
return yaml.dump(dict(data), sort_keys=False)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
|
||||||
|
@ -2056,7 +2056,8 @@ class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
|||||||
obj.get_connection_status_display(),
|
obj.get_connection_status_display(),
|
||||||
])
|
])
|
||||||
csv_data.append(csv)
|
csv_data.append(csv)
|
||||||
return csv_data
|
|
||||||
|
return '\n'.join(csv_data)
|
||||||
|
|
||||||
|
|
||||||
class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||||
@ -2087,7 +2088,8 @@ class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
|||||||
obj.get_connection_status_display(),
|
obj.get_connection_status_display(),
|
||||||
])
|
])
|
||||||
csv_data.append(csv)
|
csv_data.append(csv)
|
||||||
return csv_data
|
|
||||||
|
return '\n'.join(csv_data)
|
||||||
|
|
||||||
|
|
||||||
class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||||
@ -2126,7 +2128,8 @@ class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
|||||||
obj.get_connection_status_display(),
|
obj.get_connection_status_display(),
|
||||||
])
|
])
|
||||||
csv_data.append(csv)
|
csv_data.append(csv)
|
||||||
return csv_data
|
|
||||||
|
return '\n'.join(csv_data)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -75,6 +75,14 @@ class ObjectListView(View):
|
|||||||
table = None
|
table = None
|
||||||
template_name = None
|
template_name = None
|
||||||
|
|
||||||
|
def queryset_to_yaml(self):
|
||||||
|
"""
|
||||||
|
Export the queryset of objects as concatenated YAML documents.
|
||||||
|
"""
|
||||||
|
yaml_data = [obj.to_yaml() for obj in self.queryset]
|
||||||
|
|
||||||
|
return '---\n'.join(yaml_data)
|
||||||
|
|
||||||
def queryset_to_csv(self):
|
def queryset_to_csv(self):
|
||||||
"""
|
"""
|
||||||
Export the queryset of objects as comma-separated value (CSV), using the model's to_csv() method.
|
Export the queryset of objects as comma-separated value (CSV), using the model's to_csv() method.
|
||||||
@ -90,7 +98,7 @@ class ObjectListView(View):
|
|||||||
data = csv_format(obj.to_csv())
|
data = csv_format(obj.to_csv())
|
||||||
csv_data.append(data)
|
csv_data.append(data)
|
||||||
|
|
||||||
return csv_data
|
return '\n'.join(csv_data)
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
|
||||||
@ -121,13 +129,16 @@ class ObjectListView(View):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Check for YAML export support
|
||||||
|
elif 'export' in request.GET and hasattr(model, 'to_yaml'):
|
||||||
|
response = HttpResponse(self.queryset_to_yaml(), content_type='text/yaml')
|
||||||
|
filename = 'netbox_{}.yaml'.format(self.queryset.model._meta.verbose_name_plural)
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename)
|
||||||
|
return response
|
||||||
|
|
||||||
# Fall back to built-in CSV formatting if export requested but no template specified
|
# Fall back to built-in CSV formatting if export requested but no template specified
|
||||||
elif 'export' in request.GET and hasattr(model, 'to_csv'):
|
elif 'export' in request.GET and hasattr(model, 'to_csv'):
|
||||||
data = self.queryset_to_csv()
|
response = HttpResponse(self.queryset_to_csv(), content_type='text/csv')
|
||||||
response = HttpResponse(
|
|
||||||
'\n'.join(data),
|
|
||||||
content_type='text/csv'
|
|
||||||
)
|
|
||||||
filename = 'netbox_{}.csv'.format(self.queryset.model._meta.verbose_name_plural)
|
filename = 'netbox_{}.csv'.format(self.queryset.model._meta.verbose_name_plural)
|
||||||
response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename)
|
response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename)
|
||||||
return response
|
return response
|
||||||
|
Loading…
Reference in New Issue
Block a user