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

View File

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

View File

@ -10,7 +10,12 @@ __all__ = (
class CustomFieldsMixin:
"""
Extend a Form to include custom field support.
Attributes:
model: The model class
"""
model = None
def __init__(self, *args, **kwargs):
self.custom_fields = {}
@ -22,7 +27,7 @@ class CustomFieldsMixin:
"""
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.")
return ContentType.objects.get_for_model(self.model)

View File

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

View File

@ -5,7 +5,7 @@ from django.db.models import Q
from extras.choices import CustomFieldFilterLogicChoices, CustomFieldTypeChoices
from extras.forms.customfields import CustomFieldsMixin
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
__all__ = (
@ -61,7 +61,7 @@ class NetBoxModelCSVForm(CSVModelForm, NetBoxModelForm):
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
fields and adding/removing tags.
@ -69,6 +69,8 @@ class NetBoxModelBulkEditForm(BootstrapMixin, CustomFieldsMixin, BulkEditMixin,
Attributes:
nullable_fields: A list of field names indicating which fields support being set to null/empty
"""
nullable_fields = ()
add_tags = DynamicModelMultipleChoiceField(
queryset=Tag.objects.all(),
required=False

View File

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

View File

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

View File

@ -10,7 +10,6 @@ from .widgets import APISelect, APISelectMultiple, ClearableFileInput, StaticSel
__all__ = (
'BootstrapMixin',
'BulkEditForm',
'BulkEditMixin',
'BulkRenameForm',
'ConfirmationForm',
'CSVModelForm',
@ -65,17 +64,6 @@ class BootstrapMixin:
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
#
@ -94,8 +82,11 @@ class ConfirmationForm(BootstrapMixin, ReturnURLForm):
confirm = forms.BooleanField(required=True, widget=forms.HiddenInput(), initial=True)
class BulkEditForm(BootstrapMixin, BulkEditMixin, forms.Form):
pass
class BulkEditForm(BootstrapMixin, forms.Form):
"""
Provides bulk edit support for objects.
"""
nullable_fields = ()
class BulkRenameForm(BootstrapMixin, forms.Form):

View File

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

View File

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