mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 20:12:00 -06:00
CSV import/export custom fields
This commit is contained in:
parent
789cf827f2
commit
f1d5e28f13
@ -46,7 +46,7 @@ class ProviderForm(BootstrapMixin, CustomFieldForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ProviderCSVForm(forms.ModelForm):
|
class ProviderCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -144,7 +144,7 @@ class CircuitTypeForm(BootstrapMixin, forms.ModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class CircuitTypeCSVForm(forms.ModelForm):
|
class CircuitTypeCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -187,7 +187,7 @@ class CircuitForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CircuitCSVForm(forms.ModelForm):
|
class CircuitCSVForm(CustomFieldForm):
|
||||||
provider = forms.ModelChoiceField(
|
provider = forms.ModelChoiceField(
|
||||||
queryset=Provider.objects.all(),
|
queryset=Provider.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
|
@ -151,7 +151,7 @@ class RegionForm(BootstrapMixin, forms.ModelForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class RegionCSVForm(forms.ModelForm):
|
class RegionCSVForm(CustomFieldForm):
|
||||||
parent = forms.ModelChoiceField(
|
parent = forms.ModelChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -231,7 +231,7 @@ class SiteForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SiteCSVForm(forms.ModelForm):
|
class SiteCSVForm(CustomFieldForm):
|
||||||
status = CSVChoiceField(
|
status = CSVChoiceField(
|
||||||
choices=SITE_STATUS_CHOICES,
|
choices=SITE_STATUS_CHOICES,
|
||||||
required=False,
|
required=False,
|
||||||
@ -355,7 +355,7 @@ class RackGroupForm(BootstrapMixin, forms.ModelForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class RackGroupCSVForm(forms.ModelForm):
|
class RackGroupCSVForm(CustomFieldForm):
|
||||||
site = forms.ModelChoiceField(
|
site = forms.ModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
@ -411,7 +411,7 @@ class RackRoleForm(BootstrapMixin, forms.ModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class RackRoleCSVForm(forms.ModelForm):
|
class RackRoleCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -472,7 +472,7 @@ class RackForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class RackCSVForm(forms.ModelForm):
|
class RackCSVForm(CustomFieldForm):
|
||||||
site = forms.ModelChoiceField(
|
site = forms.ModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
@ -852,7 +852,7 @@ class ManufacturerForm(BootstrapMixin, forms.ModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ManufacturerCSVForm(forms.ModelForm):
|
class ManufacturerCSVForm(CustomFieldForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Manufacturer
|
model = Manufacturer
|
||||||
@ -890,7 +890,7 @@ class DeviceTypeForm(BootstrapMixin, CustomFieldForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class DeviceTypeCSVForm(forms.ModelForm):
|
class DeviceTypeCSVForm(CustomFieldForm):
|
||||||
manufacturer = forms.ModelChoiceField(
|
manufacturer = forms.ModelChoiceField(
|
||||||
queryset=Manufacturer.objects.all(),
|
queryset=Manufacturer.objects.all(),
|
||||||
required=True,
|
required=True,
|
||||||
@ -1308,7 +1308,7 @@ class DeviceRoleForm(BootstrapMixin, forms.ModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class DeviceRoleCSVForm(forms.ModelForm):
|
class DeviceRoleCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -1342,7 +1342,7 @@ class PlatformForm(BootstrapMixin, forms.ModelForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class PlatformCSVForm(forms.ModelForm):
|
class PlatformCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
manufacturer = forms.ModelChoiceField(
|
manufacturer = forms.ModelChoiceField(
|
||||||
queryset=Manufacturer.objects.all(),
|
queryset=Manufacturer.objects.all(),
|
||||||
@ -1564,7 +1564,7 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
self.initial['rack'] = self.instance.parent_bay.device.rack_id
|
self.initial['rack'] = self.instance.parent_bay.device.rack_id
|
||||||
|
|
||||||
|
|
||||||
class BaseDeviceCSVForm(forms.ModelForm):
|
class BaseDeviceCSVForm(CustomFieldForm):
|
||||||
device_role = forms.ModelChoiceField(
|
device_role = forms.ModelChoiceField(
|
||||||
queryset=DeviceRole.objects.all(),
|
queryset=DeviceRole.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
@ -2919,7 +2919,7 @@ class CableForm(BootstrapMixin, forms.ModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class CableCSVForm(forms.ModelForm):
|
class CableCSVForm(CustomFieldForm):
|
||||||
|
|
||||||
# Termination A
|
# Termination A
|
||||||
side_a_device = FlexibleModelChoiceField(
|
side_a_device = FlexibleModelChoiceField(
|
||||||
@ -3294,7 +3294,7 @@ class InventoryItemForm(BootstrapMixin, forms.ModelForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class InventoryItemCSVForm(forms.ModelForm):
|
class InventoryItemCSVForm(CustomFieldForm):
|
||||||
device = FlexibleModelChoiceField(
|
device = FlexibleModelChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
@ -3623,7 +3623,7 @@ class PowerPanelForm(BootstrapMixin, forms.ModelForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class PowerPanelCSVForm(forms.ModelForm):
|
class PowerPanelCSVForm(CustomFieldForm):
|
||||||
site = forms.ModelChoiceField(
|
site = forms.ModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
@ -3747,7 +3747,7 @@ class PowerFeedForm(BootstrapMixin, CustomFieldForm):
|
|||||||
self.initial['site'] = self.instance.power_panel.site
|
self.initial['site'] = self.instance.power_panel.site
|
||||||
|
|
||||||
|
|
||||||
class PowerFeedCSVForm(forms.ModelForm):
|
class PowerFeedCSVForm(CustomFieldForm):
|
||||||
site = forms.ModelChoiceField(
|
site = forms.ModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
|
@ -48,7 +48,7 @@ class VRFForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class VRFCSVForm(forms.ModelForm):
|
class VRFCSVForm(CustomFieldForm):
|
||||||
tenant = forms.ModelChoiceField(
|
tenant = forms.ModelChoiceField(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -118,7 +118,7 @@ class RIRForm(BootstrapMixin, forms.ModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class RIRCSVForm(forms.ModelForm):
|
class RIRCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -165,7 +165,7 @@ class AggregateForm(BootstrapMixin, CustomFieldForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AggregateCSVForm(forms.ModelForm):
|
class AggregateCSVForm(CustomFieldForm):
|
||||||
rir = forms.ModelChoiceField(
|
rir = forms.ModelChoiceField(
|
||||||
queryset=RIR.objects.all(),
|
queryset=RIR.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
@ -247,7 +247,7 @@ class RoleForm(BootstrapMixin, forms.ModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class RoleCSVForm(forms.ModelForm):
|
class RoleCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -340,7 +340,7 @@ class PrefixForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
self.fields['vrf'].empty_label = 'Global'
|
self.fields['vrf'].empty_label = 'Global'
|
||||||
|
|
||||||
|
|
||||||
class PrefixCSVForm(forms.ModelForm):
|
class PrefixCSVForm(CustomFieldForm):
|
||||||
vrf = FlexibleModelChoiceField(
|
vrf = FlexibleModelChoiceField(
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
to_field_name='rd',
|
to_field_name='rd',
|
||||||
@ -759,7 +759,7 @@ class IPAddressBulkAddForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
self.fields['vrf'].empty_label = 'Global'
|
self.fields['vrf'].empty_label = 'Global'
|
||||||
|
|
||||||
|
|
||||||
class IPAddressCSVForm(forms.ModelForm):
|
class IPAddressCSVForm(CustomFieldForm):
|
||||||
vrf = FlexibleModelChoiceField(
|
vrf = FlexibleModelChoiceField(
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
to_field_name='rd',
|
to_field_name='rd',
|
||||||
@ -1025,7 +1025,7 @@ class VLANGroupForm(BootstrapMixin, forms.ModelForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class VLANGroupCSVForm(forms.ModelForm):
|
class VLANGroupCSVForm(CustomFieldForm):
|
||||||
site = forms.ModelChoiceField(
|
site = forms.ModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -1122,7 +1122,7 @@ class VLANForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class VLANCSVForm(forms.ModelForm):
|
class VLANCSVForm(CustomFieldForm):
|
||||||
site = forms.ModelChoiceField(
|
site = forms.ModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -50,7 +50,7 @@ class SecretRoleForm(BootstrapMixin, forms.ModelForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SecretRoleCSVForm(forms.ModelForm):
|
class SecretRoleCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -113,7 +113,7 @@ class SecretForm(BootstrapMixin, CustomFieldForm):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class SecretCSVForm(forms.ModelForm):
|
class SecretCSVForm(CustomFieldForm):
|
||||||
device = FlexibleModelChoiceField(
|
device = FlexibleModelChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
|
@ -23,7 +23,7 @@ class TenantGroupForm(BootstrapMixin, forms.ModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TenantGroupCSVForm(forms.ModelForm):
|
class TenantGroupCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -57,7 +57,7 @@ class TenantForm(BootstrapMixin, CustomFieldForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class TenantCSVForm(forms.ModelForm):
|
class TenantCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
group = forms.ModelChoiceField(
|
group = forms.ModelChoiceField(
|
||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
|
@ -149,6 +149,9 @@ def example_choices(field, arg=3):
|
|||||||
break
|
break
|
||||||
if not value or not label:
|
if not value or not label:
|
||||||
continue
|
continue
|
||||||
|
# Handling for custom fields
|
||||||
|
if hasattr(label, 'value'):
|
||||||
|
label = label.value
|
||||||
examples.append(label)
|
examples.append(label)
|
||||||
return ', '.join(examples) or 'None'
|
return ', '.join(examples) or 'None'
|
||||||
|
|
||||||
|
@ -78,15 +78,28 @@ class ObjectListView(View):
|
|||||||
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.
|
||||||
"""
|
"""
|
||||||
csv_data = []
|
csv_data = []
|
||||||
|
custom_fields = []
|
||||||
|
|
||||||
# Start with the column headers
|
# Start with the column headers
|
||||||
headers = ','.join(self.queryset.model.csv_headers)
|
headers = ','.join(self.queryset.model.csv_headers)
|
||||||
|
|
||||||
|
# Add custom field headers
|
||||||
|
content_type = ContentType.objects.get_for_model(self.queryset.model)
|
||||||
|
|
||||||
|
for custom_field in CustomField.objects.filter(obj_type=content_type):
|
||||||
|
headers += ',cf_{}'.format(custom_field.name)
|
||||||
|
custom_fields.append(custom_field.name)
|
||||||
|
|
||||||
csv_data.append(headers)
|
csv_data.append(headers)
|
||||||
|
|
||||||
# Iterate through the queryset appending each object
|
# Iterate through the queryset appending each object
|
||||||
for obj in self.queryset:
|
for obj in self.queryset:
|
||||||
data = csv_format(obj.to_csv())
|
data = obj.to_csv()
|
||||||
csv_data.append(data)
|
|
||||||
|
for custom_field in custom_fields:
|
||||||
|
data += (obj.cf.get(custom_field, ''),)
|
||||||
|
|
||||||
|
csv_data.append(csv_format(data))
|
||||||
|
|
||||||
return csv_data
|
return csv_data
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class ClusterTypeForm(BootstrapMixin, forms.ModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ClusterTypeCSVForm(forms.ModelForm):
|
class ClusterTypeCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -62,7 +62,7 @@ class ClusterGroupForm(BootstrapMixin, forms.ModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ClusterGroupCSVForm(forms.ModelForm):
|
class ClusterGroupCSVForm(CustomFieldForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -101,7 +101,7 @@ class ClusterForm(BootstrapMixin, CustomFieldForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ClusterCSVForm(forms.ModelForm):
|
class ClusterCSVForm(CustomFieldForm):
|
||||||
type = forms.ModelChoiceField(
|
type = forms.ModelChoiceField(
|
||||||
queryset=ClusterType.objects.all(),
|
queryset=ClusterType.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
@ -416,7 +416,7 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
self.fields['primary_ip6'].widget.attrs['readonly'] = True
|
self.fields['primary_ip6'].widget.attrs['readonly'] = True
|
||||||
|
|
||||||
|
|
||||||
class VirtualMachineCSVForm(forms.ModelForm):
|
class VirtualMachineCSVForm(CustomFieldForm):
|
||||||
status = CSVChoiceField(
|
status = CSVChoiceField(
|
||||||
choices=VM_STATUS_CHOICES,
|
choices=VM_STATUS_CHOICES,
|
||||||
required=False,
|
required=False,
|
||||||
|
Loading…
Reference in New Issue
Block a user