2
0
Эх сурвалжийг харах

#4347: Rename NetBoxModelCSVForm to NetBoxModelImportForm

jeremystretch 3 жил өмнө
parent
commit
23c0ca456f

+ 16 - 11
docs/plugins/development/forms.md

@@ -4,11 +4,11 @@
 
 NetBox provides several base form classes for use by plugins.
 
-| Form Class                | Purpose                              |
-|---------------------------|--------------------------------------|
-| `NetBoxModelForm`         | Create/edit individual objects       |
-| `NetBoxModelCSVForm`      | Bulk import objects from CSV data    |
-| `NetBoxModelBulkEditForm` | Edit multiple objects simultaneously |
+| Form Class                 | Purpose                              |
+|----------------------------|--------------------------------------|
+| `NetBoxModelForm`          | Create/edit individual objects       |
+| `NetBoxModelImportForm`    | Bulk import objects from CSV data    |
+| `NetBoxModelBulkEditForm`  | Edit multiple objects simultaneously |
 | `NetBoxModelFilterSetForm` | Filter objects within a list view   |
 
 ### `NetBoxModelForm`
@@ -45,19 +45,20 @@ class MyModelForm(NetBoxModelForm):
 !!! tip "Comment fields"
     If your form has a `comments` field, there's no need to list it; this will always appear last on the page.
 
-### `NetBoxModelCSVForm`
+### `NetBoxModelImportForm`
 
-This form facilitates the bulk import of new objects from CSV data. As with model forms, you'll need to declare a `Meta` subclass specifying the associated `model` and `fields`. NetBox also provides several form fields suitable for import various types of CSV data, listed below.
+This form facilitates the bulk import of new objects from CSV, JSON, or YAML data. As with model forms, you'll need to declare a `Meta` subclass specifying the associated `model` and `fields`. NetBox also provides several form fields suitable for import various types of CSV data, listed below.
 
 **Example**
 
 ```python
 from dcim.models import Site
-from netbox.forms import NetBoxModelCSVForm
+from netbox.forms import NetBoxModelImportForm
 from utilities.forms import CSVModelChoiceField
 from .models import MyModel
 
-class MyModelCSVForm(NetBoxModelCSVForm):
+
+class MyModelImportForm(NetBoxModelImportForm):
     site = CSVModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
@@ -69,6 +70,9 @@ class MyModelCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'status', 'site', 'comments')
 ```
 
+!!! note "Previously NetBoxModelCSVForm"
+    This form class was previously named `NetBoxModelCSVForm`. It was renamed in NetBox v3.4 to convey support for JSON and YAML formats in addition to CSV. The `NetBoxModelCSVForm` class has been retained for backward compatibility and functions exactly the same as `NetBoxModelImportForm`. However, plugin authors should be aware that this backward compatability will be removed in NetBox v3.5.
+
 ### `NetBoxModelBulkEditForm`
 
 This form facilitates editing multiple objects in bulk. Unlike a model form, this form does not have a child `Meta` class, and must explicitly define each field. All fields in a bulk edit form are generally declared with `required=False`.
@@ -84,11 +88,12 @@ This form facilitates editing multiple objects in bulk. Unlike a model form, thi
 ```python
 from django import forms
 from dcim.models import Site
-from netbox.forms import NetBoxModelCSVForm
+from netbox.forms import NetBoxModelImportForm
 from utilities.forms import CommentField, DynamicModelChoiceField
 from .models import MyModel, MyModelStatusChoices
 
-class MyModelEditForm(NetBoxModelCSVForm):
+
+class MyModelEditForm(NetBoxModelImportForm):
     name = forms.CharField(
         required=False
     )

+ 1 - 0
docs/release-notes/version-3.4.md

@@ -10,6 +10,7 @@
 * The `noc_contact`, `admin_contact`, and `portal_url` fields have been removed from the provider model. Please replicate any data remaining in these fields to the contact model introduced in NetBox v3.1 prior to upgrading.
 * The `content_type` field on the CustomLink and ExportTemplate models have been renamed to `content_types` and now supports the assignment of multiple content types.
 * The `cf` property on an object with custom fields now returns deserialized values. For example, a custom field referencing an object will return the object instance rather than its numeric ID. To access the raw serialized values, use `custom_field_data` instead.
+* The `NetBoxModelCSVForm` class has been renamed to `NetBoxModelImportForm`. Backward compatability with the previous name has been retained for this release, but will be dropped in NetBox v3.5.
 
 ### New Features
 

+ 9 - 9
netbox/circuits/forms/bulk_import.py

@@ -1,19 +1,19 @@
 from circuits.choices import CircuitStatusChoices
 from circuits.models import *
 from django.utils.translation import gettext as _
-from netbox.forms import NetBoxModelCSVForm
+from netbox.forms import NetBoxModelImportForm
 from tenancy.models import Tenant
 from utilities.forms import CSVChoiceField, CSVModelChoiceField, SlugField
 
 __all__ = (
-    'CircuitCSVForm',
-    'CircuitTypeCSVForm',
-    'ProviderCSVForm',
-    'ProviderNetworkCSVForm',
+    'CircuitImportForm',
+    'CircuitTypeImportForm',
+    'ProviderImportForm',
+    'ProviderNetworkImportForm',
 )
 
 
-class ProviderCSVForm(NetBoxModelCSVForm):
+class ProviderImportForm(NetBoxModelImportForm):
     slug = SlugField()
 
     class Meta:
@@ -23,7 +23,7 @@ class ProviderCSVForm(NetBoxModelCSVForm):
         )
 
 
-class ProviderNetworkCSVForm(NetBoxModelCSVForm):
+class ProviderNetworkImportForm(NetBoxModelImportForm):
     provider = CSVModelChoiceField(
         queryset=Provider.objects.all(),
         to_field_name='name',
@@ -37,7 +37,7 @@ class ProviderNetworkCSVForm(NetBoxModelCSVForm):
         ]
 
 
-class CircuitTypeCSVForm(NetBoxModelCSVForm):
+class CircuitTypeImportForm(NetBoxModelImportForm):
     slug = SlugField()
 
     class Meta:
@@ -48,7 +48,7 @@ class CircuitTypeCSVForm(NetBoxModelCSVForm):
         }
 
 
-class CircuitCSVForm(NetBoxModelCSVForm):
+class CircuitImportForm(NetBoxModelImportForm):
     provider = CSVModelChoiceField(
         queryset=Provider.objects.all(),
         to_field_name='name',

+ 4 - 4
netbox/circuits/views.py

@@ -57,7 +57,7 @@ class ProviderDeleteView(generic.ObjectDeleteView):
 
 class ProviderBulkImportView(generic.BulkImportView):
     queryset = Provider.objects.all()
-    model_form = forms.ProviderCSVForm
+    model_form = forms.ProviderImportForm
     table = tables.ProviderTable
 
 
@@ -122,7 +122,7 @@ class ProviderNetworkDeleteView(generic.ObjectDeleteView):
 
 class ProviderNetworkBulkImportView(generic.BulkImportView):
     queryset = ProviderNetwork.objects.all()
-    model_form = forms.ProviderNetworkCSVForm
+    model_form = forms.ProviderNetworkImportForm
     table = tables.ProviderNetworkTable
 
 
@@ -179,7 +179,7 @@ class CircuitTypeDeleteView(generic.ObjectDeleteView):
 
 class CircuitTypeBulkImportView(generic.BulkImportView):
     queryset = CircuitType.objects.all()
-    model_form = forms.CircuitTypeCSVForm
+    model_form = forms.CircuitTypeImportForm
     table = tables.CircuitTypeTable
 
 
@@ -231,7 +231,7 @@ class CircuitDeleteView(generic.ObjectDeleteView):
 
 class CircuitBulkImportView(generic.BulkImportView):
     queryset = Circuit.objects.all()
-    model_form = forms.CircuitCSVForm
+    model_form = forms.CircuitImportForm
     table = tables.CircuitTable
 
 

+ 64 - 64
netbox/dcim/forms/bulk_import.py

@@ -9,48 +9,48 @@ from dcim.choices import *
 from dcim.constants import *
 from dcim.models import *
 from ipam.models import VRF
-from netbox.forms import NetBoxModelCSVForm
+from netbox.forms import NetBoxModelImportForm
 from tenancy.models import Tenant
 from utilities.forms import CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVTypedChoiceField, SlugField
 from virtualization.models import Cluster
 from wireless.choices import WirelessRoleChoices
 
 __all__ = (
-    'CableCSVForm',
-    'ChildDeviceCSVForm',
-    'ConsolePortCSVForm',
-    'ConsoleServerPortCSVForm',
-    'DeviceBayCSVForm',
-    'DeviceCSVForm',
-    'DeviceRoleCSVForm',
+    'CableImportForm',
+    'ChildDeviceImportForm',
+    'ConsolePortImportForm',
+    'ConsoleServerPortImportForm',
+    'DeviceBayImportForm',
+    'DeviceImportForm',
+    'DeviceRoleImportForm',
     'DeviceTypeImportForm',
-    'FrontPortCSVForm',
-    'InterfaceCSVForm',
-    'InventoryItemCSVForm',
-    'InventoryItemRoleCSVForm',
-    'LocationCSVForm',
-    'ManufacturerCSVForm',
-    'ModuleCSVForm',
-    'ModuleBayCSVForm',
+    'FrontPortImportForm',
+    'InterfaceImportForm',
+    'InventoryItemImportForm',
+    'InventoryItemRoleImportForm',
+    'LocationImportForm',
+    'ManufacturerImportForm',
+    'ModuleImportForm',
+    'ModuleBayImportForm',
     'ModuleTypeImportForm',
-    'PlatformCSVForm',
-    'PowerFeedCSVForm',
-    'PowerOutletCSVForm',
-    'PowerPanelCSVForm',
-    'PowerPortCSVForm',
-    'RackCSVForm',
-    'RackReservationCSVForm',
-    'RackRoleCSVForm',
-    'RearPortCSVForm',
-    'RegionCSVForm',
-    'SiteCSVForm',
-    'SiteGroupCSVForm',
-    'VirtualChassisCSVForm',
-    'VirtualDeviceContextCSVForm'
+    'PlatformImportForm',
+    'PowerFeedImportForm',
+    'PowerOutletImportForm',
+    'PowerPanelImportForm',
+    'PowerPortImportForm',
+    'RackImportForm',
+    'RackReservationImportForm',
+    'RackRoleImportForm',
+    'RearPortImportForm',
+    'RegionImportForm',
+    'SiteImportForm',
+    'SiteGroupImportForm',
+    'VirtualChassisImportForm',
+    'VirtualDeviceContextImportForm'
 )
 
 
-class RegionCSVForm(NetBoxModelCSVForm):
+class RegionImportForm(NetBoxModelImportForm):
     parent = CSVModelChoiceField(
         queryset=Region.objects.all(),
         required=False,
@@ -63,7 +63,7 @@ class RegionCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'slug', 'parent', 'description', 'tags')
 
 
-class SiteGroupCSVForm(NetBoxModelCSVForm):
+class SiteGroupImportForm(NetBoxModelImportForm):
     parent = CSVModelChoiceField(
         queryset=SiteGroup.objects.all(),
         required=False,
@@ -76,7 +76,7 @@ class SiteGroupCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'slug', 'parent', 'description')
 
 
-class SiteCSVForm(NetBoxModelCSVForm):
+class SiteImportForm(NetBoxModelImportForm):
     status = CSVChoiceField(
         choices=SiteStatusChoices,
         help_text=_('Operational status')
@@ -113,7 +113,7 @@ class SiteCSVForm(NetBoxModelCSVForm):
         }
 
 
-class LocationCSVForm(NetBoxModelCSVForm):
+class LocationImportForm(NetBoxModelImportForm):
     site = CSVModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
@@ -144,7 +144,7 @@ class LocationCSVForm(NetBoxModelCSVForm):
         fields = ('site', 'parent', 'name', 'slug', 'status', 'tenant', 'description', 'tags')
 
 
-class RackRoleCSVForm(NetBoxModelCSVForm):
+class RackRoleImportForm(NetBoxModelImportForm):
     slug = SlugField()
 
     class Meta:
@@ -155,7 +155,7 @@ class RackRoleCSVForm(NetBoxModelCSVForm):
         }
 
 
-class RackCSVForm(NetBoxModelCSVForm):
+class RackImportForm(NetBoxModelImportForm):
     site = CSVModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name'
@@ -214,7 +214,7 @@ class RackCSVForm(NetBoxModelCSVForm):
             self.fields['location'].queryset = self.fields['location'].queryset.filter(**params)
 
 
-class RackReservationCSVForm(NetBoxModelCSVForm):
+class RackReservationImportForm(NetBoxModelImportForm):
     site = CSVModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
@@ -264,14 +264,14 @@ class RackReservationCSVForm(NetBoxModelCSVForm):
             self.fields['rack'].queryset = self.fields['rack'].queryset.filter(**params)
 
 
-class ManufacturerCSVForm(NetBoxModelCSVForm):
+class ManufacturerImportForm(NetBoxModelImportForm):
 
     class Meta:
         model = Manufacturer
         fields = ('name', 'slug', 'description', 'tags')
 
 
-class DeviceTypeImportForm(NetBoxModelCSVForm):
+class DeviceTypeImportForm(NetBoxModelImportForm):
     manufacturer = forms.ModelChoiceField(
         queryset=Manufacturer.objects.all(),
         to_field_name='name'
@@ -285,7 +285,7 @@ class DeviceTypeImportForm(NetBoxModelCSVForm):
         ]
 
 
-class ModuleTypeImportForm(NetBoxModelCSVForm):
+class ModuleTypeImportForm(NetBoxModelImportForm):
     manufacturer = forms.ModelChoiceField(
         queryset=Manufacturer.objects.all(),
         to_field_name='name'
@@ -296,7 +296,7 @@ class ModuleTypeImportForm(NetBoxModelCSVForm):
         fields = ['manufacturer', 'model', 'part_number', 'description', 'comments']
 
 
-class DeviceRoleCSVForm(NetBoxModelCSVForm):
+class DeviceRoleImportForm(NetBoxModelImportForm):
     slug = SlugField()
 
     class Meta:
@@ -307,7 +307,7 @@ class DeviceRoleCSVForm(NetBoxModelCSVForm):
         }
 
 
-class PlatformCSVForm(NetBoxModelCSVForm):
+class PlatformImportForm(NetBoxModelImportForm):
     slug = SlugField()
     manufacturer = CSVModelChoiceField(
         queryset=Manufacturer.objects.all(),
@@ -321,7 +321,7 @@ class PlatformCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args', 'description', 'tags')
 
 
-class BaseDeviceCSVForm(NetBoxModelCSVForm):
+class BaseDeviceImportForm(NetBoxModelImportForm):
     device_role = CSVModelChoiceField(
         queryset=DeviceRole.objects.all(),
         to_field_name='name',
@@ -384,7 +384,7 @@ class BaseDeviceCSVForm(NetBoxModelCSVForm):
             self.fields['device_type'].queryset = self.fields['device_type'].queryset.filter(**params)
 
 
-class DeviceCSVForm(BaseDeviceCSVForm):
+class DeviceImportForm(BaseDeviceImportForm):
     site = CSVModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
@@ -413,7 +413,7 @@ class DeviceCSVForm(BaseDeviceCSVForm):
         help_text=_('Airflow direction')
     )
 
-    class Meta(BaseDeviceCSVForm.Meta):
+    class Meta(BaseDeviceImportForm.Meta):
         fields = [
             'name', 'device_role', 'tenant', 'manufacturer', 'device_type', 'platform', 'serial', 'asset_tag', 'status',
             'site', 'location', 'rack', 'position', 'face', 'airflow', 'virtual_chassis', 'vc_position', 'vc_priority',
@@ -437,7 +437,7 @@ class DeviceCSVForm(BaseDeviceCSVForm):
             self.fields['rack'].queryset = self.fields['rack'].queryset.filter(**params)
 
 
-class ModuleCSVForm(NetBoxModelCSVForm):
+class ModuleImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -466,7 +466,7 @@ class ModuleCSVForm(NetBoxModelCSVForm):
             self.fields['module_bay'].queryset = self.fields['module_bay'].queryset.filter(**params)
 
 
-class ChildDeviceCSVForm(BaseDeviceCSVForm):
+class ChildDeviceImportForm(BaseDeviceImportForm):
     parent = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name',
@@ -478,7 +478,7 @@ class ChildDeviceCSVForm(BaseDeviceCSVForm):
         help_text=_('Device bay in which this device is installed')
     )
 
-    class Meta(BaseDeviceCSVForm.Meta):
+    class Meta(BaseDeviceImportForm.Meta):
         fields = [
             'name', 'device_role', 'tenant', 'manufacturer', 'device_type', 'platform', 'serial', 'asset_tag', 'status',
             'parent', 'device_bay', 'virtual_chassis', 'vc_position', 'vc_priority', 'cluster', 'comments', 'tags'
@@ -512,7 +512,7 @@ class ChildDeviceCSVForm(BaseDeviceCSVForm):
 # Device components
 #
 
-class ConsolePortCSVForm(NetBoxModelCSVForm):
+class ConsolePortImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -535,7 +535,7 @@ class ConsolePortCSVForm(NetBoxModelCSVForm):
         fields = ('device', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'tags')
 
 
-class ConsoleServerPortCSVForm(NetBoxModelCSVForm):
+class ConsoleServerPortImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -558,7 +558,7 @@ class ConsoleServerPortCSVForm(NetBoxModelCSVForm):
         fields = ('device', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'tags')
 
 
-class PowerPortCSVForm(NetBoxModelCSVForm):
+class PowerPortImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -576,7 +576,7 @@ class PowerPortCSVForm(NetBoxModelCSVForm):
         )
 
 
-class PowerOutletCSVForm(NetBoxModelCSVForm):
+class PowerOutletImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -625,7 +625,7 @@ class PowerOutletCSVForm(NetBoxModelCSVForm):
             self.fields['power_port'].queryset = PowerPort.objects.none()
 
 
-class InterfaceCSVForm(NetBoxModelCSVForm):
+class InterfaceImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -712,7 +712,7 @@ class InterfaceCSVForm(NetBoxModelCSVForm):
             return self.cleaned_data['enabled']
 
 
-class FrontPortCSVForm(NetBoxModelCSVForm):
+class FrontPortImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -760,7 +760,7 @@ class FrontPortCSVForm(NetBoxModelCSVForm):
             self.fields['rear_port'].queryset = RearPort.objects.none()
 
 
-class RearPortCSVForm(NetBoxModelCSVForm):
+class RearPortImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -778,7 +778,7 @@ class RearPortCSVForm(NetBoxModelCSVForm):
         }
 
 
-class ModuleBayCSVForm(NetBoxModelCSVForm):
+class ModuleBayImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -789,7 +789,7 @@ class ModuleBayCSVForm(NetBoxModelCSVForm):
         fields = ('device', 'name', 'label', 'position', 'description', 'tags')
 
 
-class DeviceBayCSVForm(NetBoxModelCSVForm):
+class DeviceBayImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -835,7 +835,7 @@ class DeviceBayCSVForm(NetBoxModelCSVForm):
             self.fields['installed_device'].queryset = Interface.objects.none()
 
 
-class InventoryItemCSVForm(NetBoxModelCSVForm):
+class InventoryItemImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name'
@@ -884,7 +884,7 @@ class InventoryItemCSVForm(NetBoxModelCSVForm):
 # Device component roles
 #
 
-class InventoryItemRoleCSVForm(NetBoxModelCSVForm):
+class InventoryItemRoleImportForm(NetBoxModelImportForm):
     slug = SlugField()
 
     class Meta:
@@ -899,7 +899,7 @@ class InventoryItemRoleCSVForm(NetBoxModelCSVForm):
 # Cables
 #
 
-class CableCSVForm(NetBoxModelCSVForm):
+class CableImportForm(NetBoxModelImportForm):
     # Termination A
     side_a_device = CSVModelChoiceField(
         queryset=Device.objects.all(),
@@ -1004,7 +1004,7 @@ class CableCSVForm(NetBoxModelCSVForm):
 # Virtual chassis
 #
 
-class VirtualChassisCSVForm(NetBoxModelCSVForm):
+class VirtualChassisImportForm(NetBoxModelImportForm):
     master = CSVModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name',
@@ -1021,7 +1021,7 @@ class VirtualChassisCSVForm(NetBoxModelCSVForm):
 # Power
 #
 
-class PowerPanelCSVForm(NetBoxModelCSVForm):
+class PowerPanelImportForm(NetBoxModelImportForm):
     site = CSVModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
@@ -1047,7 +1047,7 @@ class PowerPanelCSVForm(NetBoxModelCSVForm):
             self.fields['location'].queryset = self.fields['location'].queryset.filter(**params)
 
 
-class PowerFeedCSVForm(NetBoxModelCSVForm):
+class PowerFeedImportForm(NetBoxModelImportForm):
     site = CSVModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
@@ -1115,7 +1115,7 @@ class PowerFeedCSVForm(NetBoxModelCSVForm):
             self.fields['rack'].queryset = self.fields['rack'].queryset.filter(**params)
 
 
-class VirtualDeviceContextCSVForm(NetBoxModelCSVForm):
+class VirtualDeviceContextImportForm(NetBoxModelImportForm):
 
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),

+ 29 - 29
netbox/dcim/views.py

@@ -248,7 +248,7 @@ class RegionDeleteView(generic.ObjectDeleteView):
 
 class RegionBulkImportView(generic.BulkImportView):
     queryset = Region.objects.all()
-    model_form = forms.RegionCSVForm
+    model_form = forms.RegionImportForm
     table = tables.RegionTable
 
 
@@ -336,7 +336,7 @@ class SiteGroupDeleteView(generic.ObjectDeleteView):
 
 class SiteGroupBulkImportView(generic.BulkImportView):
     queryset = SiteGroup.objects.all()
-    model_form = forms.SiteGroupCSVForm
+    model_form = forms.SiteGroupImportForm
     table = tables.SiteGroupTable
 
 
@@ -442,7 +442,7 @@ class SiteDeleteView(generic.ObjectDeleteView):
 
 class SiteBulkImportView(generic.BulkImportView):
     queryset = Site.objects.all()
-    model_form = forms.SiteCSVForm
+    model_form = forms.SiteImportForm
     table = tables.SiteTable
 
 
@@ -535,7 +535,7 @@ class LocationDeleteView(generic.ObjectDeleteView):
 
 class LocationBulkImportView(generic.BulkImportView):
     queryset = Location.objects.all()
-    model_form = forms.LocationCSVForm
+    model_form = forms.LocationImportForm
     table = tables.LocationTable
 
 
@@ -609,7 +609,7 @@ class RackRoleDeleteView(generic.ObjectDeleteView):
 
 class RackRoleBulkImportView(generic.BulkImportView):
     queryset = RackRole.objects.all()
-    model_form = forms.RackRoleCSVForm
+    model_form = forms.RackRoleImportForm
     table = tables.RackRoleTable
 
 
@@ -751,7 +751,7 @@ class RackDeleteView(generic.ObjectDeleteView):
 
 class RackBulkImportView(generic.BulkImportView):
     queryset = Rack.objects.all()
-    model_form = forms.RackCSVForm
+    model_form = forms.RackImportForm
     table = tables.RackTable
 
 
@@ -804,7 +804,7 @@ class RackReservationDeleteView(generic.ObjectDeleteView):
 
 class RackReservationImportView(generic.BulkImportView):
     queryset = RackReservation.objects.all()
-    model_form = forms.RackReservationCSVForm
+    model_form = forms.RackReservationImportForm
     table = tables.RackReservationTable
 
     def save_object(self, obj_form, request):
@@ -886,7 +886,7 @@ class ManufacturerDeleteView(generic.ObjectDeleteView):
 
 class ManufacturerBulkImportView(generic.BulkImportView):
     queryset = Manufacturer.objects.all()
-    model_form = forms.ManufacturerCSVForm
+    model_form = forms.ManufacturerImportForm
     table = tables.ManufacturerTable
 
 
@@ -1730,7 +1730,7 @@ class DeviceRoleDeleteView(generic.ObjectDeleteView):
 
 class DeviceRoleBulkImportView(generic.BulkImportView):
     queryset = DeviceRole.objects.all()
-    model_form = forms.DeviceRoleCSVForm
+    model_form = forms.DeviceRoleImportForm
     table = tables.DeviceRoleTable
 
 
@@ -1796,7 +1796,7 @@ class PlatformDeleteView(generic.ObjectDeleteView):
 
 class PlatformBulkImportView(generic.BulkImportView):
     queryset = Platform.objects.all()
-    model_form = forms.PlatformCSVForm
+    model_form = forms.PlatformImportForm
     table = tables.PlatformTable
 
 
@@ -2020,14 +2020,14 @@ class DeviceConfigContextView(ObjectConfigContextView):
 
 class DeviceBulkImportView(generic.BulkImportView):
     queryset = Device.objects.all()
-    model_form = forms.DeviceCSVForm
+    model_form = forms.DeviceImportForm
     table = tables.DeviceImportTable
     template_name = 'dcim/device_import.html'
 
 
 class ChildDeviceBulkImportView(generic.BulkImportView):
     queryset = Device.objects.all()
-    model_form = forms.ChildDeviceCSVForm
+    model_form = forms.ChildDeviceImportForm
     table = tables.DeviceImportTable
     template_name = 'dcim/device_import_child.html'
 
@@ -2151,7 +2151,7 @@ class ModuleDeleteView(generic.ObjectDeleteView):
 
 class ModuleBulkImportView(generic.BulkImportView):
     queryset = Module.objects.all()
-    model_form = forms.ModuleCSVForm
+    model_form = forms.ModuleImportForm
     table = tables.ModuleTable
 
 
@@ -2204,7 +2204,7 @@ class ConsolePortDeleteView(generic.ObjectDeleteView):
 
 class ConsolePortBulkImportView(generic.BulkImportView):
     queryset = ConsolePort.objects.all()
-    model_form = forms.ConsolePortCSVForm
+    model_form = forms.ConsolePortImportForm
     table = tables.ConsolePortTable
 
 
@@ -2269,7 +2269,7 @@ class ConsoleServerPortDeleteView(generic.ObjectDeleteView):
 
 class ConsoleServerPortBulkImportView(generic.BulkImportView):
     queryset = ConsoleServerPort.objects.all()
-    model_form = forms.ConsoleServerPortCSVForm
+    model_form = forms.ConsoleServerPortImportForm
     table = tables.ConsoleServerPortTable
 
 
@@ -2334,7 +2334,7 @@ class PowerPortDeleteView(generic.ObjectDeleteView):
 
 class PowerPortBulkImportView(generic.BulkImportView):
     queryset = PowerPort.objects.all()
-    model_form = forms.PowerPortCSVForm
+    model_form = forms.PowerPortImportForm
     table = tables.PowerPortTable
 
 
@@ -2399,7 +2399,7 @@ class PowerOutletDeleteView(generic.ObjectDeleteView):
 
 class PowerOutletBulkImportView(generic.BulkImportView):
     queryset = PowerOutlet.objects.all()
-    model_form = forms.PowerOutletCSVForm
+    model_form = forms.PowerOutletImportForm
     table = tables.PowerOutletTable
 
 
@@ -2517,7 +2517,7 @@ class InterfaceDeleteView(generic.ObjectDeleteView):
 
 class InterfaceBulkImportView(generic.BulkImportView):
     queryset = Interface.objects.all()
-    model_form = forms.InterfaceCSVForm
+    model_form = forms.InterfaceImportForm
     table = tables.InterfaceTable
 
 
@@ -2582,7 +2582,7 @@ class FrontPortDeleteView(generic.ObjectDeleteView):
 
 class FrontPortBulkImportView(generic.BulkImportView):
     queryset = FrontPort.objects.all()
-    model_form = forms.FrontPortCSVForm
+    model_form = forms.FrontPortImportForm
     table = tables.FrontPortTable
 
 
@@ -2647,7 +2647,7 @@ class RearPortDeleteView(generic.ObjectDeleteView):
 
 class RearPortBulkImportView(generic.BulkImportView):
     queryset = RearPort.objects.all()
-    model_form = forms.RearPortCSVForm
+    model_form = forms.RearPortImportForm
     table = tables.RearPortTable
 
 
@@ -2712,7 +2712,7 @@ class ModuleBayDeleteView(generic.ObjectDeleteView):
 
 class ModuleBayBulkImportView(generic.BulkImportView):
     queryset = ModuleBay.objects.all()
-    model_form = forms.ModuleBayCSVForm
+    model_form = forms.ModuleBayImportForm
     table = tables.ModuleBayTable
 
 
@@ -2838,7 +2838,7 @@ class DeviceBayDepopulateView(generic.ObjectEditView):
 
 class DeviceBayBulkImportView(generic.BulkImportView):
     queryset = DeviceBay.objects.all()
-    model_form = forms.DeviceBayCSVForm
+    model_form = forms.DeviceBayImportForm
     table = tables.DeviceBayTable
 
 
@@ -2906,7 +2906,7 @@ class InventoryItemDeleteView(generic.ObjectDeleteView):
 
 class InventoryItemBulkImportView(generic.BulkImportView):
     queryset = InventoryItem.objects.all()
-    model_form = forms.InventoryItemCSVForm
+    model_form = forms.InventoryItemImportForm
     table = tables.InventoryItemTable
 
 
@@ -2963,7 +2963,7 @@ class InventoryItemRoleDeleteView(generic.ObjectDeleteView):
 
 class InventoryItemRoleBulkImportView(generic.BulkImportView):
     queryset = InventoryItemRole.objects.all()
-    model_form = forms.InventoryItemRoleCSVForm
+    model_form = forms.InventoryItemRoleImportForm
     table = tables.InventoryItemRoleTable
 
 
@@ -3158,7 +3158,7 @@ class CableDeleteView(generic.ObjectDeleteView):
 
 class CableBulkImportView(generic.BulkImportView):
     queryset = Cable.objects.all()
-    model_form = forms.CableCSVForm
+    model_form = forms.CableImportForm
     table = tables.CableTable
 
 
@@ -3441,7 +3441,7 @@ class VirtualChassisRemoveMemberView(ObjectPermissionRequiredMixin, GetReturnURL
 
 class VirtualChassisBulkImportView(generic.BulkImportView):
     queryset = VirtualChassis.objects.all()
-    model_form = forms.VirtualChassisCSVForm
+    model_form = forms.VirtualChassisImportForm
     table = tables.VirtualChassisTable
 
 
@@ -3503,7 +3503,7 @@ class PowerPanelDeleteView(generic.ObjectDeleteView):
 
 class PowerPanelBulkImportView(generic.BulkImportView):
     queryset = PowerPanel.objects.all()
-    model_form = forms.PowerPanelCSVForm
+    model_form = forms.PowerPanelImportForm
     table = tables.PowerPanelTable
 
 
@@ -3551,7 +3551,7 @@ class PowerFeedDeleteView(generic.ObjectDeleteView):
 
 class PowerFeedBulkImportView(generic.BulkImportView):
     queryset = PowerFeed.objects.all()
-    model_form = forms.PowerFeedCSVForm
+    model_form = forms.PowerFeedImportForm
     table = tables.PowerFeedTable
 
 
@@ -3611,7 +3611,7 @@ class VirtualDeviceContextDeleteView(generic.ObjectDeleteView):
 
 class VirtualDeviceContextBulkImportView(generic.BulkImportView):
     queryset = VirtualDeviceContext.objects.all()
-    model_form = forms.VirtualDeviceContextCSVForm
+    model_form = forms.VirtualDeviceContextImportForm
     table = tables.VirtualDeviceContextTable
 
 

+ 12 - 12
netbox/extras/forms/bulk_import.py

@@ -10,16 +10,16 @@ from extras.utils import FeatureQuery
 from utilities.forms import CSVChoiceField, CSVContentTypeField, CSVModelForm, CSVMultipleContentTypeField, SlugField
 
 __all__ = (
-    'CustomFieldCSVForm',
-    'CustomLinkCSVForm',
-    'ExportTemplateCSVForm',
-    'SavedFilterCSVForm',
-    'TagCSVForm',
-    'WebhookCSVForm',
+    'CustomFieldImportForm',
+    'CustomLinkImportForm',
+    'ExportTemplateImportForm',
+    'SavedFilterImportForm',
+    'TagImportForm',
+    'WebhookImportForm',
 )
 
 
-class CustomFieldCSVForm(CSVModelForm):
+class CustomFieldImportForm(CSVModelForm):
     content_types = CSVMultipleContentTypeField(
         queryset=ContentType.objects.all(),
         limit_choices_to=FeatureQuery('custom_fields'),
@@ -54,7 +54,7 @@ class CustomFieldCSVForm(CSVModelForm):
         )
 
 
-class CustomLinkCSVForm(CSVModelForm):
+class CustomLinkImportForm(CSVModelForm):
     content_types = CSVMultipleContentTypeField(
         queryset=ContentType.objects.all(),
         limit_choices_to=FeatureQuery('custom_links'),
@@ -69,7 +69,7 @@ class CustomLinkCSVForm(CSVModelForm):
         )
 
 
-class ExportTemplateCSVForm(CSVModelForm):
+class ExportTemplateImportForm(CSVModelForm):
     content_types = CSVMultipleContentTypeField(
         queryset=ContentType.objects.all(),
         limit_choices_to=FeatureQuery('export_templates'),
@@ -83,7 +83,7 @@ class ExportTemplateCSVForm(CSVModelForm):
         )
 
 
-class SavedFilterCSVForm(CSVModelForm):
+class SavedFilterImportForm(CSVModelForm):
     content_types = CSVMultipleContentTypeField(
         queryset=ContentType.objects.all(),
         help_text=_("One or more assigned object types")
@@ -96,7 +96,7 @@ class SavedFilterCSVForm(CSVModelForm):
         )
 
 
-class WebhookCSVForm(CSVModelForm):
+class WebhookImportForm(CSVModelForm):
     content_types = CSVMultipleContentTypeField(
         queryset=ContentType.objects.all(),
         limit_choices_to=FeatureQuery('webhooks'),
@@ -112,7 +112,7 @@ class WebhookCSVForm(CSVModelForm):
         )
 
 
-class TagCSVForm(CSVModelForm):
+class TagImportForm(CSVModelForm):
     slug = SlugField()
 
     class Meta:

+ 3 - 3
netbox/extras/tests/test_customfields.py

@@ -6,7 +6,7 @@ from django.urls import reverse
 from rest_framework import status
 
 from dcim.filtersets import SiteFilterSet
-from dcim.forms import SiteCSVForm
+from dcim.forms import SiteImportForm
 from dcim.models import Manufacturer, Rack, Site
 from extras.choices import *
 from extras.models import CustomField
@@ -983,7 +983,7 @@ class CustomFieldImportTest(TestCase):
             'slug': 'site-1',
         }
 
-        form = SiteCSVForm(data=form_data)
+        form = SiteImportForm(data=form_data)
         self.assertFalse(form.is_valid())
         self.assertIn('cf_text', form.errors)
 
@@ -997,7 +997,7 @@ class CustomFieldImportTest(TestCase):
             'cf_select': 'Choice X'
         }
 
-        form = SiteCSVForm(data=form_data)
+        form = SiteImportForm(data=form_data)
         self.assertFalse(form.is_valid())
         self.assertIn('cf_select', form.errors)
 

+ 6 - 6
netbox/extras/views.py

@@ -49,7 +49,7 @@ class CustomFieldDeleteView(generic.ObjectDeleteView):
 
 class CustomFieldBulkImportView(generic.BulkImportView):
     queryset = CustomField.objects.all()
-    model_form = forms.CustomFieldCSVForm
+    model_form = forms.CustomFieldImportForm
     table = tables.CustomFieldTable
 
 
@@ -95,7 +95,7 @@ class CustomLinkDeleteView(generic.ObjectDeleteView):
 
 class CustomLinkBulkImportView(generic.BulkImportView):
     queryset = CustomLink.objects.all()
-    model_form = forms.CustomLinkCSVForm
+    model_form = forms.CustomLinkImportForm
     table = tables.CustomLinkTable
 
 
@@ -141,7 +141,7 @@ class ExportTemplateDeleteView(generic.ObjectDeleteView):
 
 class ExportTemplateBulkImportView(generic.BulkImportView):
     queryset = ExportTemplate.objects.all()
-    model_form = forms.ExportTemplateCSVForm
+    model_form = forms.ExportTemplateImportForm
     table = tables.ExportTemplateTable
 
 
@@ -209,7 +209,7 @@ class SavedFilterDeleteView(SavedFilterMixin, generic.ObjectDeleteView):
 
 class SavedFilterBulkImportView(SavedFilterMixin, generic.BulkImportView):
     queryset = SavedFilter.objects.all()
-    model_form = forms.SavedFilterCSVForm
+    model_form = forms.SavedFilterImportForm
     table = tables.SavedFilterTable
 
 
@@ -255,7 +255,7 @@ class WebhookDeleteView(generic.ObjectDeleteView):
 
 class WebhookBulkImportView(generic.BulkImportView):
     queryset = Webhook.objects.all()
-    model_form = forms.WebhookCSVForm
+    model_form = forms.WebhookImportForm
     table = tables.WebhookTable
 
 
@@ -324,7 +324,7 @@ class TagDeleteView(generic.ObjectDeleteView):
 
 class TagBulkImportView(generic.BulkImportView):
     queryset = Tag.objects.all()
-    model_form = forms.TagCSVForm
+    model_form = forms.TagImportForm
     table = tables.TagTable
 
 

+ 33 - 33
netbox/ipam/forms/bulk_import.py

@@ -7,32 +7,32 @@ from dcim.models import Device, Interface, Site
 from ipam.choices import *
 from ipam.constants import *
 from ipam.models import *
-from netbox.forms import NetBoxModelCSVForm
+from netbox.forms import NetBoxModelImportForm
 from tenancy.models import Tenant
 from utilities.forms import CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, SlugField
 from virtualization.models import VirtualMachine, VMInterface
 
 __all__ = (
-    'AggregateCSVForm',
-    'ASNCSVForm',
-    'FHRPGroupCSVForm',
-    'IPAddressCSVForm',
-    'IPRangeCSVForm',
-    'L2VPNCSVForm',
-    'L2VPNTerminationCSVForm',
-    'PrefixCSVForm',
-    'RIRCSVForm',
-    'RoleCSVForm',
-    'RouteTargetCSVForm',
-    'ServiceCSVForm',
-    'ServiceTemplateCSVForm',
-    'VLANCSVForm',
-    'VLANGroupCSVForm',
-    'VRFCSVForm',
+    'AggregateImportForm',
+    'ASNImportForm',
+    'FHRPGroupImportForm',
+    'IPAddressImportForm',
+    'IPRangeImportForm',
+    'L2VPNImportForm',
+    'L2VPNTerminationImportForm',
+    'PrefixImportForm',
+    'RIRImportForm',
+    'RoleImportForm',
+    'RouteTargetImportForm',
+    'ServiceImportForm',
+    'ServiceTemplateImportForm',
+    'VLANImportForm',
+    'VLANGroupImportForm',
+    'VRFImportForm',
 )
 
 
-class VRFCSVForm(NetBoxModelCSVForm):
+class VRFImportForm(NetBoxModelImportForm):
     tenant = CSVModelChoiceField(
         queryset=Tenant.objects.all(),
         required=False,
@@ -45,7 +45,7 @@ class VRFCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'rd', 'tenant', 'enforce_unique', 'description', 'comments', 'tags')
 
 
-class RouteTargetCSVForm(NetBoxModelCSVForm):
+class RouteTargetImportForm(NetBoxModelImportForm):
     tenant = CSVModelChoiceField(
         queryset=Tenant.objects.all(),
         required=False,
@@ -58,7 +58,7 @@ class RouteTargetCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'tenant', 'description', 'comments', 'tags')
 
 
-class RIRCSVForm(NetBoxModelCSVForm):
+class RIRImportForm(NetBoxModelImportForm):
     slug = SlugField()
 
     class Meta:
@@ -69,7 +69,7 @@ class RIRCSVForm(NetBoxModelCSVForm):
         }
 
 
-class AggregateCSVForm(NetBoxModelCSVForm):
+class AggregateImportForm(NetBoxModelImportForm):
     rir = CSVModelChoiceField(
         queryset=RIR.objects.all(),
         to_field_name='name',
@@ -87,7 +87,7 @@ class AggregateCSVForm(NetBoxModelCSVForm):
         fields = ('prefix', 'rir', 'tenant', 'date_added', 'description', 'comments', 'tags')
 
 
-class ASNCSVForm(NetBoxModelCSVForm):
+class ASNImportForm(NetBoxModelImportForm):
     rir = CSVModelChoiceField(
         queryset=RIR.objects.all(),
         to_field_name='name',
@@ -105,7 +105,7 @@ class ASNCSVForm(NetBoxModelCSVForm):
         fields = ('asn', 'rir', 'tenant', 'description', 'comments', 'tags')
 
 
-class RoleCSVForm(NetBoxModelCSVForm):
+class RoleImportForm(NetBoxModelImportForm):
     slug = SlugField()
 
     class Meta:
@@ -113,7 +113,7 @@ class RoleCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'slug', 'weight', 'description', 'tags')
 
 
-class PrefixCSVForm(NetBoxModelCSVForm):
+class PrefixImportForm(NetBoxModelImportForm):
     vrf = CSVModelChoiceField(
         queryset=VRF.objects.all(),
         to_field_name='name',
@@ -177,7 +177,7 @@ class PrefixCSVForm(NetBoxModelCSVForm):
                 self.fields['vlan'].queryset = self.fields['vlan'].queryset.filter(**params)
 
 
-class IPRangeCSVForm(NetBoxModelCSVForm):
+class IPRangeImportForm(NetBoxModelImportForm):
     vrf = CSVModelChoiceField(
         queryset=VRF.objects.all(),
         to_field_name='name',
@@ -208,7 +208,7 @@ class IPRangeCSVForm(NetBoxModelCSVForm):
         )
 
 
-class IPAddressCSVForm(NetBoxModelCSVForm):
+class IPAddressImportForm(NetBoxModelImportForm):
     vrf = CSVModelChoiceField(
         queryset=VRF.objects.all(),
         to_field_name='name',
@@ -315,7 +315,7 @@ class IPAddressCSVForm(NetBoxModelCSVForm):
         return ipaddress
 
 
-class FHRPGroupCSVForm(NetBoxModelCSVForm):
+class FHRPGroupImportForm(NetBoxModelImportForm):
     protocol = CSVChoiceField(
         choices=FHRPGroupProtocolChoices
     )
@@ -329,7 +329,7 @@ class FHRPGroupCSVForm(NetBoxModelCSVForm):
         fields = ('protocol', 'group_id', 'auth_type', 'auth_key', 'name', 'description', 'comments', 'tags')
 
 
-class VLANGroupCSVForm(NetBoxModelCSVForm):
+class VLANGroupImportForm(NetBoxModelImportForm):
     slug = SlugField()
     scope_type = CSVContentTypeField(
         queryset=ContentType.objects.filter(model__in=VLANGROUP_SCOPE_TYPES),
@@ -357,7 +357,7 @@ class VLANGroupCSVForm(NetBoxModelCSVForm):
         }
 
 
-class VLANCSVForm(NetBoxModelCSVForm):
+class VLANImportForm(NetBoxModelImportForm):
     site = CSVModelChoiceField(
         queryset=Site.objects.all(),
         required=False,
@@ -396,7 +396,7 @@ class VLANCSVForm(NetBoxModelCSVForm):
         }
 
 
-class ServiceTemplateCSVForm(NetBoxModelCSVForm):
+class ServiceTemplateImportForm(NetBoxModelImportForm):
     protocol = CSVChoiceField(
         choices=ServiceProtocolChoices,
         help_text=_('IP protocol')
@@ -407,7 +407,7 @@ class ServiceTemplateCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'protocol', 'ports', 'description', 'comments', 'tags')
 
 
-class ServiceCSVForm(NetBoxModelCSVForm):
+class ServiceImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         required=False,
@@ -430,7 +430,7 @@ class ServiceCSVForm(NetBoxModelCSVForm):
         fields = ('device', 'virtual_machine', 'name', 'protocol', 'ports', 'description', 'comments', 'tags')
 
 
-class L2VPNCSVForm(NetBoxModelCSVForm):
+class L2VPNImportForm(NetBoxModelImportForm):
     tenant = CSVModelChoiceField(
         queryset=Tenant.objects.all(),
         required=False,
@@ -446,7 +446,7 @@ class L2VPNCSVForm(NetBoxModelCSVForm):
         fields = ('identifier', 'name', 'slug', 'type', 'description', 'comments', 'tags')
 
 
-class L2VPNTerminationCSVForm(NetBoxModelCSVForm):
+class L2VPNTerminationImportForm(NetBoxModelImportForm):
     l2vpn = CSVModelChoiceField(
         queryset=L2VPN.objects.all(),
         required=True,

+ 16 - 16
netbox/ipam/views.py

@@ -72,7 +72,7 @@ class VRFDeleteView(generic.ObjectDeleteView):
 
 class VRFBulkImportView(generic.BulkImportView):
     queryset = VRF.objects.all()
-    model_form = forms.VRFCSVForm
+    model_form = forms.VRFImportForm
     table = tables.VRFTable
 
 
@@ -133,7 +133,7 @@ class RouteTargetDeleteView(generic.ObjectDeleteView):
 
 class RouteTargetBulkImportView(generic.BulkImportView):
     queryset = RouteTarget.objects.all()
-    model_form = forms.RouteTargetCSVForm
+    model_form = forms.RouteTargetImportForm
     table = tables.RouteTargetTable
 
 
@@ -192,7 +192,7 @@ class RIRDeleteView(generic.ObjectDeleteView):
 
 class RIRBulkImportView(generic.BulkImportView):
     queryset = RIR.objects.all()
-    model_form = forms.RIRCSVForm
+    model_form = forms.RIRImportForm
     table = tables.RIRTable
 
 
@@ -265,7 +265,7 @@ class ASNDeleteView(generic.ObjectDeleteView):
 
 class ASNBulkImportView(generic.BulkImportView):
     queryset = ASN.objects.all()
-    model_form = forms.ASNCSVForm
+    model_form = forms.ASNImportForm
     table = tables.ASNTable
 
 
@@ -351,7 +351,7 @@ class AggregateDeleteView(generic.ObjectDeleteView):
 
 class AggregateBulkImportView(generic.BulkImportView):
     queryset = Aggregate.objects.all()
-    model_form = forms.AggregateCSVForm
+    model_form = forms.AggregateImportForm
     table = tables.AggregateTable
 
 
@@ -417,7 +417,7 @@ class RoleDeleteView(generic.ObjectDeleteView):
 
 class RoleBulkImportView(generic.BulkImportView):
     queryset = Role.objects.all()
-    model_form = forms.RoleCSVForm
+    model_form = forms.RoleImportForm
     table = tables.RoleTable
 
 
@@ -592,7 +592,7 @@ class PrefixDeleteView(generic.ObjectDeleteView):
 
 class PrefixBulkImportView(generic.BulkImportView):
     queryset = Prefix.objects.all()
-    model_form = forms.PrefixCSVForm
+    model_form = forms.PrefixImportForm
     table = tables.PrefixTable
 
 
@@ -655,7 +655,7 @@ class IPRangeDeleteView(generic.ObjectDeleteView):
 
 class IPRangeBulkImportView(generic.BulkImportView):
     queryset = IPRange.objects.all()
-    model_form = forms.IPRangeCSVForm
+    model_form = forms.IPRangeImportForm
     table = tables.IPRangeTable
 
 
@@ -836,7 +836,7 @@ class IPAddressBulkCreateView(generic.BulkCreateView):
 
 class IPAddressBulkImportView(generic.BulkImportView):
     queryset = IPAddress.objects.all()
-    model_form = forms.IPAddressCSVForm
+    model_form = forms.IPAddressImportForm
     table = tables.IPAddressTable
 
 
@@ -910,7 +910,7 @@ class VLANGroupDeleteView(generic.ObjectDeleteView):
 
 class VLANGroupBulkImportView(generic.BulkImportView):
     queryset = VLANGroup.objects.all()
-    model_form = forms.VLANGroupCSVForm
+    model_form = forms.VLANGroupImportForm
     table = tables.VLANGroupTable
 
 
@@ -999,7 +999,7 @@ class FHRPGroupDeleteView(generic.ObjectDeleteView):
 
 class FHRPGroupBulkImportView(generic.BulkImportView):
     queryset = FHRPGroup.objects.all()
-    model_form = forms.FHRPGroupCSVForm
+    model_form = forms.FHRPGroupImportForm
     table = tables.FHRPGroupTable
 
 
@@ -1113,7 +1113,7 @@ class VLANDeleteView(generic.ObjectDeleteView):
 
 class VLANBulkImportView(generic.BulkImportView):
     queryset = VLAN.objects.all()
-    model_form = forms.VLANCSVForm
+    model_form = forms.VLANImportForm
     table = tables.VLANTable
 
 
@@ -1159,7 +1159,7 @@ class ServiceTemplateDeleteView(generic.ObjectDeleteView):
 
 class ServiceTemplateBulkImportView(generic.BulkImportView):
     queryset = ServiceTemplate.objects.all()
-    model_form = forms.ServiceTemplateCSVForm
+    model_form = forms.ServiceTemplateImportForm
     table = tables.ServiceTemplateTable
 
 
@@ -1212,7 +1212,7 @@ class ServiceDeleteView(generic.ObjectDeleteView):
 
 class ServiceBulkImportView(generic.BulkImportView):
     queryset = Service.objects.all()
-    model_form = forms.ServiceCSVForm
+    model_form = forms.ServiceImportForm
     table = tables.ServiceTable
 
 
@@ -1276,7 +1276,7 @@ class L2VPNDeleteView(generic.ObjectDeleteView):
 
 class L2VPNBulkImportView(generic.BulkImportView):
     queryset = L2VPN.objects.all()
-    model_form = forms.L2VPNCSVForm
+    model_form = forms.L2VPNImportForm
     table = tables.L2VPNTable
 
 
@@ -1323,7 +1323,7 @@ class L2VPNTerminationDeleteView(generic.ObjectDeleteView):
 
 class L2VPNTerminationBulkImportView(generic.BulkImportView):
     queryset = L2VPNTermination.objects.all()
-    model_form = forms.L2VPNTerminationCSVForm
+    model_form = forms.L2VPNTerminationImportForm
     table = tables.L2VPNTerminationTable
 
 

+ 11 - 2
netbox/netbox/forms/base.py

@@ -11,8 +11,9 @@ from utilities.forms import BootstrapMixin, CSVModelForm
 from utilities.forms.fields import CSVModelMultipleChoiceField, DynamicModelMultipleChoiceField
 
 __all__ = (
-    'NetBoxModelForm',
     'NetBoxModelCSVForm',
+    'NetBoxModelForm',
+    'NetBoxModelImportForm',
     'NetBoxModelBulkEditForm',
     'NetBoxModelFilterSetForm',
 )
@@ -59,7 +60,7 @@ class NetBoxModelForm(BootstrapMixin, CustomFieldsMixin, forms.ModelForm):
         return super().clean()
 
 
-class NetBoxModelCSVForm(CSVModelForm, NetBoxModelForm):
+class NetBoxModelImportForm(CSVModelForm, NetBoxModelForm):
     """
     Base form for creating a NetBox objects from CSV data. Used for bulk importing.
     """
@@ -83,6 +84,14 @@ class NetBoxModelCSVForm(CSVModelForm, NetBoxModelForm):
         return customfield.to_form_field(for_csv_import=True)
 
 
+class NetBoxModelCSVForm(NetBoxModelImportForm):
+    """
+    Maintains backward compatibility for NetBoxModelImportForm for plugins.
+    """
+    # TODO: Remove in NetBox v3.5
+    pass
+
+
 class NetBoxModelBulkEditForm(BootstrapMixin, CustomFieldsMixin, forms.Form):
     """
     Base form for modifying multiple NetBox objects (of the same type) in bulk via the UI. Adds support for custom

+ 11 - 11
netbox/tenancy/forms/bulk_import.py

@@ -1,14 +1,14 @@
 from django.utils.translation import gettext as _
-from netbox.forms import NetBoxModelCSVForm
+from netbox.forms import NetBoxModelImportForm
 from tenancy.models import *
 from utilities.forms import CSVModelChoiceField, SlugField
 
 __all__ = (
-    'ContactCSVForm',
-    'ContactGroupCSVForm',
-    'ContactRoleCSVForm',
-    'TenantCSVForm',
-    'TenantGroupCSVForm',
+    'ContactImportForm',
+    'ContactGroupImportForm',
+    'ContactRoleImportForm',
+    'TenantImportForm',
+    'TenantGroupImportForm',
 )
 
 
@@ -16,7 +16,7 @@ __all__ = (
 # Tenants
 #
 
-class TenantGroupCSVForm(NetBoxModelCSVForm):
+class TenantGroupImportForm(NetBoxModelImportForm):
     parent = CSVModelChoiceField(
         queryset=TenantGroup.objects.all(),
         required=False,
@@ -30,7 +30,7 @@ class TenantGroupCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'slug', 'parent', 'description', 'tags')
 
 
-class TenantCSVForm(NetBoxModelCSVForm):
+class TenantImportForm(NetBoxModelImportForm):
     slug = SlugField()
     group = CSVModelChoiceField(
         queryset=TenantGroup.objects.all(),
@@ -48,7 +48,7 @@ class TenantCSVForm(NetBoxModelCSVForm):
 # Contacts
 #
 
-class ContactGroupCSVForm(NetBoxModelCSVForm):
+class ContactGroupImportForm(NetBoxModelImportForm):
     parent = CSVModelChoiceField(
         queryset=ContactGroup.objects.all(),
         required=False,
@@ -62,7 +62,7 @@ class ContactGroupCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'slug', 'parent', 'description', 'tags')
 
 
-class ContactRoleCSVForm(NetBoxModelCSVForm):
+class ContactRoleImportForm(NetBoxModelImportForm):
     slug = SlugField()
 
     class Meta:
@@ -70,7 +70,7 @@ class ContactRoleCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'slug', 'description')
 
 
-class ContactCSVForm(NetBoxModelCSVForm):
+class ContactImportForm(NetBoxModelImportForm):
     group = CSVModelChoiceField(
         queryset=ContactGroup.objects.all(),
         required=False,

+ 5 - 5
netbox/tenancy/views.py

@@ -59,7 +59,7 @@ class TenantGroupDeleteView(generic.ObjectDeleteView):
 
 class TenantGroupBulkImportView(generic.BulkImportView):
     queryset = TenantGroup.objects.all()
-    model_form = forms.TenantGroupCSVForm
+    model_form = forms.TenantGroupImportForm
     table = tables.TenantGroupTable
 
 
@@ -143,7 +143,7 @@ class TenantDeleteView(generic.ObjectDeleteView):
 
 class TenantBulkImportView(generic.BulkImportView):
     queryset = Tenant.objects.all()
-    model_form = forms.TenantCSVForm
+    model_form = forms.TenantImportForm
     table = tables.TenantTable
 
 
@@ -221,7 +221,7 @@ class ContactGroupDeleteView(generic.ObjectDeleteView):
 
 class ContactGroupBulkImportView(generic.BulkImportView):
     queryset = ContactGroup.objects.all()
-    model_form = forms.ContactGroupCSVForm
+    model_form = forms.ContactGroupImportForm
     table = tables.ContactGroupTable
 
 
@@ -291,7 +291,7 @@ class ContactRoleDeleteView(generic.ObjectDeleteView):
 
 class ContactRoleBulkImportView(generic.BulkImportView):
     queryset = ContactRole.objects.all()
-    model_form = forms.ContactRoleCSVForm
+    model_form = forms.ContactRoleImportForm
     table = tables.ContactRoleTable
 
 
@@ -351,7 +351,7 @@ class ContactDeleteView(generic.ObjectDeleteView):
 
 class ContactBulkImportView(generic.BulkImportView):
     queryset = Contact.objects.all()
-    model_form = forms.ContactCSVForm
+    model_form = forms.ContactImportForm
     table = tables.ContactTable
 
 

+ 2 - 2
netbox/utilities/tests/test_forms.py

@@ -1,7 +1,7 @@
 from django import forms
 from django.test import TestCase
 
-from ipam.forms import IPAddressCSVForm
+from ipam.forms import IPAddressImportForm
 from utilities.forms.fields import CSVDataField
 from utilities.forms.utils import expand_alphanumeric_pattern, expand_ipaddress_pattern
 
@@ -288,7 +288,7 @@ class ExpandAlphanumeric(TestCase):
 class CSVDataFieldTest(TestCase):
 
     def setUp(self):
-        self.field = CSVDataField(from_form=IPAddressCSVForm)
+        self.field = CSVDataField(from_form=IPAddressImportForm)
 
     def test_clean(self):
         input = """

+ 11 - 11
netbox/virtualization/forms/bulk_import.py

@@ -2,22 +2,22 @@ from dcim.choices import InterfaceModeChoices
 from dcim.models import Device, DeviceRole, Platform, Site
 from django.utils.translation import gettext as _
 from ipam.models import VRF
-from netbox.forms import NetBoxModelCSVForm
+from netbox.forms import NetBoxModelImportForm
 from tenancy.models import Tenant
 from utilities.forms import CSVChoiceField, CSVModelChoiceField, SlugField
 from virtualization.choices import *
 from virtualization.models import *
 
 __all__ = (
-    'ClusterCSVForm',
-    'ClusterGroupCSVForm',
-    'ClusterTypeCSVForm',
-    'VirtualMachineCSVForm',
-    'VMInterfaceCSVForm',
+    'ClusterImportForm',
+    'ClusterGroupImportForm',
+    'ClusterTypeImportForm',
+    'VirtualMachineImportForm',
+    'VMInterfaceImportForm',
 )
 
 
-class ClusterTypeCSVForm(NetBoxModelCSVForm):
+class ClusterTypeImportForm(NetBoxModelImportForm):
     slug = SlugField()
 
     class Meta:
@@ -25,7 +25,7 @@ class ClusterTypeCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'slug', 'description', 'tags')
 
 
-class ClusterGroupCSVForm(NetBoxModelCSVForm):
+class ClusterGroupImportForm(NetBoxModelImportForm):
     slug = SlugField()
 
     class Meta:
@@ -33,7 +33,7 @@ class ClusterGroupCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'slug', 'description', 'tags')
 
 
-class ClusterCSVForm(NetBoxModelCSVForm):
+class ClusterImportForm(NetBoxModelImportForm):
     type = CSVModelChoiceField(
         queryset=ClusterType.objects.all(),
         to_field_name='name',
@@ -67,7 +67,7 @@ class ClusterCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'type', 'group', 'status', 'site', 'description', 'comments', 'tags')
 
 
-class VirtualMachineCSVForm(NetBoxModelCSVForm):
+class VirtualMachineImportForm(NetBoxModelImportForm):
     status = CSVChoiceField(
         choices=VirtualMachineStatusChoices,
         help_text=_('Operational status')
@@ -119,7 +119,7 @@ class VirtualMachineCSVForm(NetBoxModelCSVForm):
         )
 
 
-class VMInterfaceCSVForm(NetBoxModelCSVForm):
+class VMInterfaceImportForm(NetBoxModelImportForm):
     virtual_machine = CSVModelChoiceField(
         queryset=VirtualMachine.objects.all(),
         to_field_name='name'

+ 5 - 5
netbox/virtualization/views.py

@@ -63,7 +63,7 @@ class ClusterTypeDeleteView(generic.ObjectDeleteView):
 
 class ClusterTypeBulkImportView(generic.BulkImportView):
     queryset = ClusterType.objects.all()
-    model_form = forms.ClusterTypeCSVForm
+    model_form = forms.ClusterTypeImportForm
     table = tables.ClusterTypeTable
 
 
@@ -130,7 +130,7 @@ class ClusterGroupBulkImportView(generic.BulkImportView):
     queryset = ClusterGroup.objects.annotate(
         cluster_count=count_related(Cluster, 'group')
     )
-    model_form = forms.ClusterGroupCSVForm
+    model_form = forms.ClusterGroupImportForm
     table = tables.ClusterGroupTable
 
 
@@ -217,7 +217,7 @@ class ClusterDeleteView(generic.ObjectDeleteView):
 
 class ClusterBulkImportView(generic.BulkImportView):
     queryset = Cluster.objects.all()
-    model_form = forms.ClusterCSVForm
+    model_form = forms.ClusterImportForm
     table = tables.ClusterTable
 
 
@@ -403,7 +403,7 @@ class VirtualMachineDeleteView(generic.ObjectDeleteView):
 
 class VirtualMachineBulkImportView(generic.BulkImportView):
     queryset = VirtualMachine.objects.all()
-    model_form = forms.VirtualMachineCSVForm
+    model_form = forms.VirtualMachineImportForm
     table = tables.VirtualMachineTable
 
 
@@ -491,7 +491,7 @@ class VMInterfaceDeleteView(generic.ObjectDeleteView):
 
 class VMInterfaceBulkImportView(generic.BulkImportView):
     queryset = VMInterface.objects.all()
-    model_form = forms.VMInterfaceCSVForm
+    model_form = forms.VMInterfaceImportForm
     table = tables.VMInterfaceTable
 
 

+ 7 - 7
netbox/wireless/forms/bulk_import.py

@@ -2,20 +2,20 @@ from django.utils.translation import gettext as _
 from dcim.choices import LinkStatusChoices
 from dcim.models import Interface
 from ipam.models import VLAN
-from netbox.forms import NetBoxModelCSVForm
+from netbox.forms import NetBoxModelImportForm
 from tenancy.models import Tenant
 from utilities.forms import CSVChoiceField, CSVModelChoiceField, SlugField
 from wireless.choices import *
 from wireless.models import *
 
 __all__ = (
-    'WirelessLANCSVForm',
-    'WirelessLANGroupCSVForm',
-    'WirelessLinkCSVForm',
+    'WirelessLANImportForm',
+    'WirelessLANGroupImportForm',
+    'WirelessLinkImportForm',
 )
 
 
-class WirelessLANGroupCSVForm(NetBoxModelCSVForm):
+class WirelessLANGroupImportForm(NetBoxModelImportForm):
     parent = CSVModelChoiceField(
         queryset=WirelessLANGroup.objects.all(),
         required=False,
@@ -29,7 +29,7 @@ class WirelessLANGroupCSVForm(NetBoxModelCSVForm):
         fields = ('name', 'slug', 'parent', 'description', 'tags')
 
 
-class WirelessLANCSVForm(NetBoxModelCSVForm):
+class WirelessLANImportForm(NetBoxModelImportForm):
     group = CSVModelChoiceField(
         queryset=WirelessLANGroup.objects.all(),
         required=False,
@@ -71,7 +71,7 @@ class WirelessLANCSVForm(NetBoxModelCSVForm):
         )
 
 
-class WirelessLinkCSVForm(NetBoxModelCSVForm):
+class WirelessLinkImportForm(NetBoxModelImportForm):
     status = CSVChoiceField(
         choices=LinkStatusChoices,
         help_text=_('Connection status')

+ 3 - 3
netbox/wireless/views.py

@@ -52,7 +52,7 @@ class WirelessLANGroupDeleteView(generic.ObjectDeleteView):
 
 class WirelessLANGroupBulkImportView(generic.BulkImportView):
     queryset = WirelessLANGroup.objects.all()
-    model_form = forms.WirelessLANGroupCSVForm
+    model_form = forms.WirelessLANGroupImportForm
     table = tables.WirelessLANGroupTable
 
 
@@ -123,7 +123,7 @@ class WirelessLANDeleteView(generic.ObjectDeleteView):
 
 class WirelessLANBulkImportView(generic.BulkImportView):
     queryset = WirelessLAN.objects.all()
-    model_form = forms.WirelessLANCSVForm
+    model_form = forms.WirelessLANImportForm
     table = tables.WirelessLANTable
 
 
@@ -169,7 +169,7 @@ class WirelessLinkDeleteView(generic.ObjectDeleteView):
 
 class WirelessLinkBulkImportView(generic.BulkImportView):
     queryset = WirelessLink.objects.all()
-    model_form = forms.WirelessLinkCSVForm
+    model_form = forms.WirelessLinkImportForm
     table = tables.WirelessLinkTable