Set model as attribute on bulk edit forms

This commit is contained in:
jeremystretch 2022-02-01 11:00:18 -05:00
parent 4347f624d8
commit 3621b1a0d0
10 changed files with 77 additions and 19 deletions

View File

@ -47,6 +47,7 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
label='Comments' label='Comments'
) )
model = Provider
nullable_fields = ( nullable_fields = (
'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments',
) )
@ -74,6 +75,7 @@ class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
label='Comments' label='Comments'
) )
model = ProviderNetwork
nullable_fields = ( nullable_fields = (
'service_id', 'description', 'comments', 'service_id', 'description', 'comments',
) )
@ -89,6 +91,7 @@ class CircuitTypeBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = CircuitType
nullable_fields = ('description',) nullable_fields = ('description',)
@ -128,6 +131,7 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
label='Comments' label='Comments'
) )
model = Circuit
nullable_fields = ( nullable_fields = (
'tenant', 'commit_rate', 'description', 'comments', 'tenant', 'commit_rate', 'description', 'comments',
) )

View File

@ -71,6 +71,7 @@ class RegionBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = Region
nullable_fields = ('parent', 'description') nullable_fields = ('parent', 'description')
@ -88,6 +89,7 @@ class SiteGroupBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = SiteGroup
nullable_fields = ('parent', 'description') nullable_fields = ('parent', 'description')
@ -129,6 +131,7 @@ class SiteBulkEditForm(NetBoxModelBulkEditForm):
widget=StaticSelect() widget=StaticSelect()
) )
model = Site
nullable_fields = ( nullable_fields = (
'region', 'group', 'tenant', 'asns', 'description', 'time_zone', 'region', 'group', 'tenant', 'asns', 'description', 'time_zone',
) )
@ -159,6 +162,7 @@ class LocationBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = Location
nullable_fields = ('parent', 'tenant', 'description') nullable_fields = ('parent', 'tenant', 'description')
@ -175,6 +179,7 @@ class RackRoleBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = RackRole
nullable_fields = ('color', 'description') nullable_fields = ('color', 'description')
@ -272,6 +277,7 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
label='Comments' label='Comments'
) )
model = Rack
nullable_fields = ( nullable_fields = (
'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_depth', 'outer_unit', 'comments', 'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_depth', 'outer_unit', 'comments',
) )
@ -298,6 +304,8 @@ class RackReservationBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = RackReservation
class ManufacturerBulkEditForm(NetBoxModelBulkEditForm): class ManufacturerBulkEditForm(NetBoxModelBulkEditForm):
pk = forms.ModelMultipleChoiceField( pk = forms.ModelMultipleChoiceField(
@ -309,6 +317,7 @@ class ManufacturerBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = Manufacturer
nullable_fields = ('description',) nullable_fields = ('description',)
@ -339,6 +348,7 @@ class DeviceTypeBulkEditForm(NetBoxModelBulkEditForm):
widget=StaticSelect() widget=StaticSelect()
) )
model = DeviceType
nullable_fields = ('part_number', 'airflow') nullable_fields = ('part_number', 'airflow')
@ -355,6 +365,7 @@ class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = ModuleType
nullable_fields = ('part_number',) nullable_fields = ('part_number',)
@ -376,6 +387,7 @@ class DeviceRoleBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = DeviceRole
nullable_fields = ('color', 'description') nullable_fields = ('color', 'description')
@ -398,6 +410,7 @@ class PlatformBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = Platform
nullable_fields = ('manufacturer', 'napalm_driver', 'description') nullable_fields = ('manufacturer', 'napalm_driver', 'description')
@ -456,6 +469,7 @@ class DeviceBulkEditForm(NetBoxModelBulkEditForm):
label='Serial Number' label='Serial Number'
) )
model = Device
nullable_fields = ( nullable_fields = (
'tenant', 'platform', 'serial', 'airflow', 'tenant', 'platform', 'serial', 'airflow',
) )
@ -483,6 +497,7 @@ class ModuleBulkEditForm(NetBoxModelBulkEditForm):
label='Serial Number' label='Serial Number'
) )
model = Module
nullable_fields = ('serial',) nullable_fields = ('serial',)
@ -525,6 +540,7 @@ class CableBulkEditForm(NetBoxModelBulkEditForm):
widget=StaticSelect() widget=StaticSelect()
) )
model = Cable
nullable_fields = ( nullable_fields = (
'type', 'status', 'tenant', 'label', 'color', 'length', 'type', 'status', 'tenant', 'label', 'color', 'length',
) )
@ -551,6 +567,7 @@ class VirtualChassisBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = VirtualChassis
nullable_fields = ('domain',) nullable_fields = ('domain',)
@ -589,6 +606,7 @@ class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
} }
) )
model = PowerPanel
nullable_fields = ('location',) nullable_fields = ('location',)
@ -647,6 +665,7 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
label='Comments' label='Comments'
) )
model = PowerFeed
nullable_fields = ('location', 'comments') nullable_fields = ('location', 'comments')
@ -918,6 +937,7 @@ class ConsolePortBulkEditForm(
widget=BulkEditNullBooleanSelect widget=BulkEditNullBooleanSelect
) )
model = ConsolePort
nullable_fields = ('label', 'description') nullable_fields = ('label', 'description')
@ -934,6 +954,7 @@ class ConsoleServerPortBulkEditForm(
widget=BulkEditNullBooleanSelect widget=BulkEditNullBooleanSelect
) )
model = ConsoleServerPort
nullable_fields = ('label', 'description') nullable_fields = ('label', 'description')
@ -950,6 +971,7 @@ class PowerPortBulkEditForm(
widget=BulkEditNullBooleanSelect widget=BulkEditNullBooleanSelect
) )
model = PowerPort
nullable_fields = ('label', 'description') nullable_fields = ('label', 'description')
@ -972,6 +994,7 @@ class PowerOutletBulkEditForm(
widget=BulkEditNullBooleanSelect widget=BulkEditNullBooleanSelect
) )
model = PowerOutlet
nullable_fields = ('label', 'type', 'feed_leg', 'power_port', 'description') nullable_fields = ('label', 'type', 'feed_leg', 'power_port', 'description')
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -1051,6 +1074,7 @@ class InterfaceBulkEditForm(
label='VRF' label='VRF'
) )
model = Interface
nullable_fields = ( nullable_fields = (
'label', 'parent', 'bridge', 'lag', 'speed', 'duplex', 'mac_address', 'wwn', 'mtu', 'description', 'mode', 'label', 'parent', 'bridge', 'lag', 'speed', 'duplex', 'mac_address', 'wwn', 'mtu', 'description', 'mode',
'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'untagged_vlan', 'tagged_vlans', 'vrf', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'untagged_vlan', 'tagged_vlans', 'vrf',
@ -1119,6 +1143,7 @@ class FrontPortBulkEditForm(
widget=forms.MultipleHiddenInput() widget=forms.MultipleHiddenInput()
) )
model = FrontPort
nullable_fields = ('label', 'description') nullable_fields = ('label', 'description')
@ -1131,6 +1156,7 @@ class RearPortBulkEditForm(
widget=forms.MultipleHiddenInput() widget=forms.MultipleHiddenInput()
) )
model = RearPort
nullable_fields = ('label', 'description') nullable_fields = ('label', 'description')
@ -1143,6 +1169,7 @@ class ModuleBayBulkEditForm(
widget=forms.MultipleHiddenInput() widget=forms.MultipleHiddenInput()
) )
model = ModuleBay
nullable_fields = ('label', 'position', 'description') nullable_fields = ('label', 'position', 'description')
@ -1155,6 +1182,7 @@ class DeviceBayBulkEditForm(
widget=forms.MultipleHiddenInput() widget=forms.MultipleHiddenInput()
) )
model = DeviceBay
nullable_fields = ('label', 'description') nullable_fields = ('label', 'description')
@ -1175,6 +1203,7 @@ class InventoryItemBulkEditForm(
required=False required=False
) )
model = InventoryItem
nullable_fields = ('label', 'role', 'manufacturer', 'part_id', 'description') nullable_fields = ('label', 'role', 'manufacturer', 'part_id', 'description')
@ -1195,4 +1224,5 @@ class InventoryItemRoleBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = InventoryItemRole
nullable_fields = ('color', 'description') nullable_fields = ('color', 'description')

View File

@ -10,7 +10,12 @@ __all__ = (
class CustomFieldsMixin: class CustomFieldsMixin:
""" """
Extend a Form to include custom field support. Extend a Form to include custom field support.
Attributes:
model: The model class
""" """
model = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.custom_fields = {} self.custom_fields = {}
@ -22,7 +27,7 @@ class CustomFieldsMixin:
""" """
Return the ContentType of the form's model. Return the ContentType of the form's model.
""" """
if not hasattr(self, 'model'): if not getattr(self, 'model', None):
raise NotImplementedError(f"{self.__class__.__name__} must specify a model class.") raise NotImplementedError(f"{self.__class__.__name__} must specify a model class.")
return ContentType.objects.get_for_model(self.model) return ContentType.objects.get_for_model(self.model)

View File

@ -49,6 +49,7 @@ class VRFBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = VRF
nullable_fields = ('tenant', 'description') nullable_fields = ('tenant', 'description')
@ -66,6 +67,7 @@ class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = RouteTarget
nullable_fields = ('tenant', 'description') nullable_fields = ('tenant', 'description')
@ -83,6 +85,7 @@ class RIRBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = RIR
nullable_fields = ('is_private', 'description') nullable_fields = ('is_private', 'description')
@ -109,6 +112,7 @@ class ASNBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = ASN
nullable_fields = ('date_added', 'description') nullable_fields = ('date_added', 'description')
@ -134,6 +138,7 @@ class AggregateBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = Aggregate
nullable_fields = ('date_added', 'description') nullable_fields = ('date_added', 'description')
@ -150,6 +155,7 @@ class RoleBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = Role
nullable_fields = ('description',) nullable_fields = ('description',)
@ -212,6 +218,7 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = Prefix
nullable_fields = ( nullable_fields = (
'site', 'vrf', 'tenant', 'role', 'description', 'site', 'vrf', 'tenant', 'role', 'description',
) )
@ -245,6 +252,7 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = IPRange
nullable_fields = ( nullable_fields = (
'vrf', 'tenant', 'role', 'description', 'vrf', 'tenant', 'role', 'description',
) )
@ -289,6 +297,7 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = IPAddress
nullable_fields = ( nullable_fields = (
'vrf', 'role', 'tenant', 'dns_name', 'description', 'vrf', 'role', 'tenant', 'dns_name', 'description',
) )
@ -325,6 +334,7 @@ class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = FHRPGroup
nullable_fields = ('auth_type', 'auth_key', 'description') nullable_fields = ('auth_type', 'auth_key', 'description')
@ -354,6 +364,7 @@ class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = VLANGroup
nullable_fields = ('site', 'description') nullable_fields = ('site', 'description')
@ -403,6 +414,7 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = VLAN
nullable_fields = ( nullable_fields = (
'site', 'group', 'tenant', 'role', 'description', 'site', 'group', 'tenant', 'role', 'description',
) )
@ -430,6 +442,7 @@ class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = ServiceTemplate
nullable_fields = ('description',) nullable_fields = ('description',)

View File

@ -5,7 +5,7 @@ from django.db.models import Q
from extras.choices import CustomFieldFilterLogicChoices, CustomFieldTypeChoices from extras.choices import CustomFieldFilterLogicChoices, CustomFieldTypeChoices
from extras.forms.customfields import CustomFieldsMixin from extras.forms.customfields import CustomFieldsMixin
from extras.models import CustomField, Tag from extras.models import CustomField, Tag
from utilities.forms import BootstrapMixin, BulkEditMixin, CSVModelForm from utilities.forms import BootstrapMixin, CSVModelForm
from utilities.forms.fields import DynamicModelMultipleChoiceField from utilities.forms.fields import DynamicModelMultipleChoiceField
__all__ = ( __all__ = (
@ -61,7 +61,7 @@ class NetBoxModelCSVForm(CSVModelForm, NetBoxModelForm):
return customfield.to_form_field(for_csv_import=True) return customfield.to_form_field(for_csv_import=True)
class NetBoxModelBulkEditForm(BootstrapMixin, CustomFieldsMixin, BulkEditMixin, forms.Form): 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 Base form for modifying multiple NetBox objects (of the same type) in bulk via the UI. Adds support for custom
fields and adding/removing tags. fields and adding/removing tags.
@ -69,6 +69,8 @@ class NetBoxModelBulkEditForm(BootstrapMixin, CustomFieldsMixin, BulkEditMixin,
Attributes: Attributes:
nullable_fields: A list of field names indicating which fields support being set to null/empty nullable_fields: A list of field names indicating which fields support being set to null/empty
""" """
nullable_fields = ()
add_tags = DynamicModelMultipleChoiceField( add_tags = DynamicModelMultipleChoiceField(
queryset=Tag.objects.all(), queryset=Tag.objects.all(),
required=False required=False

View File

@ -529,7 +529,7 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView):
initial_data['virtual_machine'] = request.GET.get('virtual_machine') initial_data['virtual_machine'] = request.GET.get('virtual_machine')
if '_apply' in request.POST: if '_apply' in request.POST:
form = self.form(model, request.POST, initial=initial_data) form = self.form(request.POST, initial=initial_data)
restrict_form_fields(form, request.user) restrict_form_fields(form, request.user)
if form.is_valid(): if form.is_valid():
@ -566,7 +566,7 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView):
logger.debug("Form validation failed") logger.debug("Form validation failed")
else: else:
form = self.form(model, initial=initial_data) form = self.form(initial=initial_data)
restrict_form_fields(form, request.user) restrict_form_fields(form, request.user)
# Retrieve objects being edited # Retrieve objects being edited

View File

@ -31,6 +31,7 @@ class TenantGroupBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = TenantGroup
nullable_fields = ('parent', 'description') nullable_fields = ('parent', 'description')
@ -44,6 +45,7 @@ class TenantBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = Tenant
nullable_fields = ('group',) nullable_fields = ('group',)
@ -65,6 +67,7 @@ class ContactGroupBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = ContactGroup
nullable_fields = ('parent', 'description') nullable_fields = ('parent', 'description')
@ -78,6 +81,7 @@ class ContactRoleBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = ContactRole
nullable_fields = ('description',) nullable_fields = ('description',)
@ -106,4 +110,5 @@ class ContactBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = Contact
nullable_fields = ('group', 'title', 'phone', 'email', 'address', 'comments') nullable_fields = ('group', 'title', 'phone', 'email', 'address', 'comments')

View File

@ -10,7 +10,6 @@ from .widgets import APISelect, APISelectMultiple, ClearableFileInput, StaticSel
__all__ = ( __all__ = (
'BootstrapMixin', 'BootstrapMixin',
'BulkEditForm', 'BulkEditForm',
'BulkEditMixin',
'BulkRenameForm', 'BulkRenameForm',
'ConfirmationForm', 'ConfirmationForm',
'CSVModelForm', 'CSVModelForm',
@ -65,17 +64,6 @@ class BootstrapMixin:
field.widget.attrs['class'] = ' '.join((css, 'form-select')).strip() field.widget.attrs['class'] = ' '.join((css, 'form-select')).strip()
class BulkEditMixin:
"""
Base form for editing multiple objects in bulk
"""
nullable_fields = ()
def __init__(self, model, *args, **kwargs):
super().__init__(*args, **kwargs)
self.model = model
# #
# Form classes # Form classes
# #
@ -94,8 +82,11 @@ class ConfirmationForm(BootstrapMixin, ReturnURLForm):
confirm = forms.BooleanField(required=True, widget=forms.HiddenInput(), initial=True) confirm = forms.BooleanField(required=True, widget=forms.HiddenInput(), initial=True)
class BulkEditForm(BootstrapMixin, BulkEditMixin, forms.Form): class BulkEditForm(BootstrapMixin, forms.Form):
pass """
Provides bulk edit support for objects.
"""
nullable_fields = ()
class BulkRenameForm(BootstrapMixin, forms.Form): class BulkRenameForm(BootstrapMixin, forms.Form):

View File

@ -33,6 +33,7 @@ class ClusterTypeBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = ClusterType
nullable_fields = ('description',) nullable_fields = ('description',)
@ -46,6 +47,7 @@ class ClusterGroupBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = ClusterGroup
nullable_fields = ('description',) nullable_fields = ('description',)
@ -87,6 +89,7 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
label='Comments' label='Comments'
) )
model = Cluster
nullable_fields = ( nullable_fields = (
'group', 'site', 'comments', 'tenant', 'group', 'site', 'comments', 'tenant',
) )
@ -141,6 +144,7 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
label='Comments' label='Comments'
) )
model = VirtualMachine
nullable_fields = ( nullable_fields = (
'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments',
) )
@ -193,6 +197,7 @@ class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = VMInterface
nullable_fields = ( nullable_fields = (
'parent', 'bridge', 'mtu', 'description', 'parent', 'bridge', 'mtu', 'description',
) )

View File

@ -29,6 +29,7 @@ class WirelessLANGroupBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
model = WirelessLANGroup
nullable_fields = ('parent', 'description') nullable_fields = ('parent', 'description')
@ -67,6 +68,7 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
label='Pre-shared key' label='Pre-shared key'
) )
model = WirelessLAN
nullable_fields = ( nullable_fields = (
'ssid', 'group', 'vlan', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'ssid', 'group', 'vlan', 'description', 'auth_type', 'auth_cipher', 'auth_psk',
) )
@ -102,6 +104,7 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
label='Pre-shared key' label='Pre-shared key'
) )
model = WirelessLink
nullable_fields = ( nullable_fields = (
'ssid', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'ssid', 'description', 'auth_type', 'auth_cipher', 'auth_psk',
) )