Explorar el Código

Enable the use of fieldsets on bulk edit forms

jeremystretch hace 4 años
padre
commit
60e87cd496

+ 14 - 1
netbox/circuits/forms/bulk_edit.py

@@ -44,6 +44,9 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Provider
+    fieldsets = (
+        (None, ('asn', 'account', 'portal_url', 'noc_contact', 'admin_contact')),
+    )
     nullable_fields = (
         'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments',
     )
@@ -56,7 +59,8 @@ class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
     )
     service_id = forms.CharField(
         max_length=100,
-        required=False
+        required=False,
+        label='Service ID'
     )
     description = forms.CharField(
         max_length=200,
@@ -68,6 +72,9 @@ class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = ProviderNetwork
+    fieldsets = (
+        (None, ('provider', 'service_id', 'description')),
+    )
     nullable_fields = (
         'service_id', 'description', 'comments',
     )
@@ -80,6 +87,9 @@ class CircuitTypeBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = CircuitType
+    fieldsets = (
+        (None, ('description',)),
+    )
     nullable_fields = ('description',)
 
 
@@ -116,6 +126,9 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Circuit
+    fieldsets = (
+        (None, ('type', 'provider', 'status', 'tenant', 'commit_rate', 'description')),
+    )
     nullable_fields = (
         'tenant', 'commit_rate', 'description', 'comments',
     )

+ 105 - 4
netbox/dcim/forms/bulk_edit.py

@@ -68,6 +68,9 @@ class RegionBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Region
+    fieldsets = (
+        (None, ('parent', 'description')),
+    )
     nullable_fields = ('parent', 'description')
 
 
@@ -82,6 +85,9 @@ class SiteGroupBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = SiteGroup
+    fieldsets = (
+        (None, ('parent', 'description')),
+    )
     nullable_fields = ('parent', 'description')
 
 
@@ -120,6 +126,9 @@ class SiteBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Site
+    fieldsets = (
+        (None, ('status', 'region', 'group', 'tenant', 'asns', 'time_zone', 'description')),
+    )
     nullable_fields = (
         'region', 'group', 'tenant', 'asns', 'description', 'time_zone',
     )
@@ -147,6 +156,9 @@ class LocationBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Location
+    fieldsets = (
+        (None, ('site', 'parent', 'tenant', 'description')),
+    )
     nullable_fields = ('parent', 'tenant', 'description')
 
 
@@ -160,6 +172,9 @@ class RackRoleBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = RackRole
+    fieldsets = (
+        (None, ('color', 'description')),
+    )
     nullable_fields = ('color', 'description')
 
 
@@ -254,6 +269,11 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Rack
+    fieldsets = (
+        ('Rack', ('status', 'role', 'tenant', 'serial', 'asset_tag')),
+        ('Location', ('region', 'site_group', 'site', 'location')),
+        ('Hardware', ('type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit')),
+    )
     nullable_fields = (
         'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_depth', 'outer_unit', 'comments',
     )
@@ -277,6 +297,9 @@ class RackReservationBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = RackReservation
+    fieldsets = (
+        (None, ('user', 'tenant', 'description')),
+    )
 
 
 class ManufacturerBulkEditForm(NetBoxModelBulkEditForm):
@@ -286,6 +309,9 @@ class ManufacturerBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Manufacturer
+    fieldsets = (
+        (None, ('description',)),
+    )
     nullable_fields = ('description',)
 
 
@@ -313,6 +339,9 @@ class DeviceTypeBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = DeviceType
+    fieldsets = (
+        (None, ('manufacturer', 'part_number', 'u_height', 'is_full_depth', 'airflow')),
+    )
     nullable_fields = ('part_number', 'airflow')
 
 
@@ -326,6 +355,9 @@ class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = ModuleType
+    fieldsets = (
+        (None, ('manufacturer', 'part_number')),
+    )
     nullable_fields = ('part_number',)
 
 
@@ -344,6 +376,9 @@ class DeviceRoleBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = DeviceRole
+    fieldsets = (
+        (None, ('color', 'vm_role', 'description')),
+    )
     nullable_fields = ('color', 'description')
 
 
@@ -363,6 +398,9 @@ class PlatformBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Platform
+    fieldsets = (
+        (None, ('manufacturer', 'napalm_driver', 'description')),
+    )
     nullable_fields = ('manufacturer', 'napalm_driver', 'description')
 
 
@@ -418,6 +456,11 @@ class DeviceBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Device
+    fieldsets = (
+        ('Device', ('device_role', 'status', 'tenant', 'platform')),
+        ('Location', ('site', 'location')),
+        ('Hardware', ('manufacturer', 'device_type', 'airflow', 'serial')),
+    )
     nullable_fields = (
         'tenant', 'platform', 'serial', 'airflow',
     )
@@ -442,6 +485,9 @@ class ModuleBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Module
+    fieldsets = (
+        (None, ('manufacturer', 'module_type', 'serial')),
+    )
     nullable_fields = ('serial',)
 
 
@@ -481,6 +527,10 @@ class CableBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Cable
+    fieldsets = (
+        (None, ('type', 'status', 'tenant', 'label')),
+        ('Attributes', ('color', 'length', 'length_unit')),
+    )
     nullable_fields = (
         'type', 'status', 'tenant', 'label', 'color', 'length',
     )
@@ -504,6 +554,9 @@ class VirtualChassisBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = VirtualChassis
+    fieldsets = (
+        (None, ('domain',)),
+    )
     nullable_fields = ('domain',)
 
 
@@ -539,6 +592,9 @@ class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = PowerPanel
+    fieldsets = (
+        (None, ('region', 'site_group', 'site', 'location')),
+    )
     nullable_fields = ('location',)
 
 
@@ -594,6 +650,10 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = PowerFeed
+    fieldsets = (
+        (None, ('power_panel', 'rack', 'status', 'type', 'mark_connected')),
+        ('Power', ('supply', 'phase', 'voltage', 'amperage', 'max_utilization'))
+    )
     nullable_fields = ('location', 'comments')
 
 
@@ -862,6 +922,9 @@ class ConsolePortBulkEditForm(
     )
 
     model = ConsolePort
+    fieldsets = (
+        (None, ('type', 'label', 'speed', 'description', 'mark_connected')),
+    )
     nullable_fields = ('label', 'description')
 
 
@@ -875,6 +938,9 @@ class ConsoleServerPortBulkEditForm(
     )
 
     model = ConsoleServerPort
+    fieldsets = (
+        (None, ('type', 'label', 'speed', 'description', 'mark_connected')),
+    )
     nullable_fields = ('label', 'description')
 
 
@@ -888,6 +954,10 @@ class PowerPortBulkEditForm(
     )
 
     model = PowerPort
+    fieldsets = (
+        (None, ('type', 'label', 'description', 'mark_connected')),
+        ('Power', ('maximum_draw', 'allocated_draw')),
+    )
     nullable_fields = ('label', 'description')
 
 
@@ -907,6 +977,10 @@ class PowerOutletBulkEditForm(
     )
 
     model = PowerOutlet
+    fieldsets = (
+        (None, ('type', 'label', 'description', 'mark_connected')),
+        ('Power', ('feed_leg', 'power_port')),
+    )
     nullable_fields = ('label', 'type', 'feed_leg', 'power_port', 'description')
 
     def __init__(self, *args, **kwargs):
@@ -923,8 +997,9 @@ class PowerOutletBulkEditForm(
 
 class InterfaceBulkEditForm(
     form_from_model(Interface, [
-        'label', 'type', 'parent', 'bridge', 'lag', 'speed', 'duplex', 'mac_address', 'wwn', 'mtu', 'mgmt_only', 'mark_connected',
-        'description', 'mode', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power',
+        'label', 'type', 'parent', 'bridge', 'lag', 'speed', 'duplex', 'mac_address', 'wwn', 'mtu', 'mgmt_only',
+        'mark_connected', 'description', 'mode', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width',
+        'tx_power',
     ]),
     NetBoxModelBulkEditForm
 ):
@@ -956,7 +1031,7 @@ class InterfaceBulkEditForm(
     )
     speed = forms.IntegerField(
         required=False,
-        widget=SelectSpeedWidget(attrs={'readonly': None}),
+        widget=SelectSpeedWidget(),
         label='Speed'
     )
     mgmt_only = forms.NullBooleanField(
@@ -983,6 +1058,14 @@ class InterfaceBulkEditForm(
     )
 
     model = Interface
+    fieldsets = (
+        (None, ('type', 'label', 'speed', 'duplex', 'description')),
+        ('Addressing', ('vrf', 'mac_address', 'wwn')),
+        ('Operation', ('mtu', 'tx_power', 'enabled', 'mgmt_only', 'mark_connected')),
+        ('Related Interfaces', ('parent', 'bridge', 'lag')),
+        ('802.1Q Switching', ('mode', 'untagged_vlan', 'tagged_vlans')),
+        ('Wireless', ('rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width')),
+    )
     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',
@@ -1047,6 +1130,9 @@ class FrontPortBulkEditForm(
     NetBoxModelBulkEditForm
 ):
     model = FrontPort
+    fieldsets = (
+        (None, ('type', 'label', 'color', 'description', 'mark_connected')),
+    )
     nullable_fields = ('label', 'description')
 
 
@@ -1055,14 +1141,20 @@ class RearPortBulkEditForm(
     NetBoxModelBulkEditForm
 ):
     model = RearPort
+    fieldsets = (
+        (None, ('type', 'label', 'color', 'description', 'mark_connected')),
+    )
     nullable_fields = ('label', 'description')
 
 
 class ModuleBayBulkEditForm(
-    form_from_model(DeviceBay, ['label', 'description']),
+    form_from_model(ModuleBay, ['label', 'position', 'description']),
     NetBoxModelBulkEditForm
 ):
     model = ModuleBay
+    fieldsets = (
+        (None, ('label', 'position', 'description')),
+    )
     nullable_fields = ('label', 'position', 'description')
 
 
@@ -1071,6 +1163,9 @@ class DeviceBayBulkEditForm(
     NetBoxModelBulkEditForm
 ):
     model = DeviceBay
+    fieldsets = (
+        (None, ('label', 'description')),
+    )
     nullable_fields = ('label', 'description')
 
 
@@ -1088,6 +1183,9 @@ class InventoryItemBulkEditForm(
     )
 
     model = InventoryItem
+    fieldsets = (
+        (None, ('label', 'role', 'manufacturer', 'part_id', 'description')),
+    )
     nullable_fields = ('label', 'role', 'manufacturer', 'part_id', 'description')
 
 
@@ -1105,4 +1203,7 @@ class InventoryItemRoleBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = InventoryItemRole
+    fieldsets = (
+        (None, ('color', 'description')),
+    )
     nullable_fields = ('color', 'description')

+ 44 - 0
netbox/ipam/forms/bulk_edit.py

@@ -46,6 +46,9 @@ class VRFBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = VRF
+    fieldsets = (
+        (None, ('tenant', 'enforce_unique', 'description')),
+    )
     nullable_fields = ('tenant', 'description')
 
 
@@ -60,6 +63,9 @@ class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = RouteTarget
+    fieldsets = (
+        (None, ('tenant', 'description')),
+    )
     nullable_fields = ('tenant', 'description')
 
 
@@ -74,6 +80,9 @@ class RIRBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = RIR
+    fieldsets = (
+        (None, ('is_private', 'description')),
+    )
     nullable_fields = ('is_private', 'description')
 
 
@@ -97,6 +106,9 @@ class ASNBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = ASN
+    fieldsets = (
+        (None, ('sites', 'rir', 'tenant', 'description')),
+    )
     nullable_fields = ('date_added', 'description')
 
 
@@ -119,6 +131,9 @@ class AggregateBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Aggregate
+    fieldsets = (
+        (None, ('rir', 'tenant', 'date_added', 'description')),
+    )
     nullable_fields = ('date_added', 'description')
 
 
@@ -132,6 +147,9 @@ class RoleBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Role
+    fieldsets = (
+        (None, ('weight', 'description')),
+    )
     nullable_fields = ('description',)
 
 
@@ -191,6 +209,11 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Prefix
+    fieldsets = (
+        (None, ('tenant', 'status', 'role', 'description')),
+        ('Site', ('region', 'site_group', 'site')),
+        ('Addressing', ('vrf', 'prefix_length', 'is_pool', 'mark_utilized')),
+    )
     nullable_fields = (
         'site', 'vrf', 'tenant', 'role', 'description',
     )
@@ -221,6 +244,9 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = IPRange
+    fieldsets = (
+        (None, ('status', 'role', 'vrf', 'tenant', 'description')),
+    )
     nullable_fields = (
         'vrf', 'tenant', 'role', 'description',
     )
@@ -262,6 +288,10 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = IPAddress
+    fieldsets = (
+        (None, ('status', 'role', 'tenant', 'description')),
+        ('Addressing', ('vrf', 'mask_length', 'dns_name')),
+    )
     nullable_fields = (
         'vrf', 'role', 'tenant', 'dns_name', 'description',
     )
@@ -295,6 +325,10 @@ class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = FHRPGroup
+    fieldsets = (
+        (None, ('protocol', 'group_id', 'description')),
+        ('Authentication', ('auth_type', 'auth_key')),
+    )
     nullable_fields = ('auth_type', 'auth_key', 'description')
 
 
@@ -321,6 +355,9 @@ class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = VLANGroup
+    fieldsets = (
+        (None, ('site', 'min_vid', 'max_vid', 'description')),
+    )
     nullable_fields = ('site', 'description')
 
 
@@ -367,6 +404,10 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = VLAN
+    fieldsets = (
+        (None, ('status', 'role', 'tenant', 'description')),
+        ('Site & Group', ('region', 'site_group', 'site', 'group')),
+    )
     nullable_fields = (
         'site', 'group', 'tenant', 'role', 'description',
     )
@@ -391,6 +432,9 @@ class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = ServiceTemplate
+    fieldsets = (
+        (None, ('protocol', 'ports', 'description')),
+    )
     nullable_fields = ('description',)
 
 

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

@@ -67,6 +67,8 @@ class NetBoxModelBulkEditForm(BootstrapMixin, CustomFieldsMixin, forms.Form):
     fields and adding/removing tags.
 
     Attributes:
+        fieldsets: An iterable of two-tuples which define a heading and field set to display per section of
+            the rendered form (optional). If not defined, the all fields will be rendered as a single section.
         nullable_fields: A list of field names indicating which fields support being set to null/empty
     """
     nullable_fields = ()

+ 1 - 1
netbox/netbox/views/generic/bulk_views.py

@@ -578,9 +578,9 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView):
             return redirect(self.get_return_url(request))
 
         return render(request, self.template_name, {
+            'model': model,
             'form': form,
             'table': table,
-            'obj_type_plural': model._meta.verbose_name_plural,
             'return_url': self.get_return_url(request),
             **self.get_extra_context(request),
         })

+ 65 - 7
netbox/templates/generic/object_bulk_edit.html

@@ -3,7 +3,7 @@
 {% load form_helpers %}
 {% load render_table from django_tables2 %}
 
-{% block title %}Editing {{ table.rows|length }} {{ obj_type_plural|bettertitle }}{% endblock %}
+{% block title %}Editing {{ table.rows|length }} {{ model|meta:"verbose_name_plural" }}{% endblock %}
 
 {% block tabs %}
   <ul class="nav nav-tabs px-3">
@@ -41,13 +41,71 @@
             <div class="col col-md-12 col-lg-10 offset-lg-1">
               <div class="card">
                 <div class="card-body">
-                  {% for field in form.visible_fields %}
-                    {% if field.name in form.nullable_fields %}
-                      {% render_field field bulk_nullable=True %}
-                    {% else %}
-                      {% render_field field %}
+                  {% if form.fieldsets %}
+
+                    {# Render grouped fields according to declared fieldsets #}
+                    {% for group, fields in form.fieldsets %}
+                      <div class="field-group mb-5">
+                        <div class="row mb-2">
+                          <h5 class="offset-sm-3">
+                            {% if group %}{{ group }}{% else %}{{ model|meta:"verbose_name" }}{% endif %}
+                          </h5>
+                        </div>
+                        {% for name in fields %}
+                          {% with field=form|getfield:name %}
+                            {% if field.name in form.nullable_fields %}
+                              {% render_field field bulk_nullable=True %}
+                            {% else %}
+                              {% render_field field %}
+                            {% endif %}
+                          {% endwith %}
+                        {% endfor %}
+                      </div>
+                    {% endfor %}
+
+                    {# Render tag add/remove fields #}
+                    {% if form.add_tags and form.remove_tags %}
+                      <div class="field-group mb-5">
+                        <div class="row mb-2">
+                          <h5 class="offset-sm-3">Tags</h5>
+                        </div>
+                        {% render_field form.add_tags %}
+                        {% render_field form.remove_tags %}
+                      </div>
                     {% endif %}
-                  {% endfor %}
+
+                    {# Render custom fields #}
+                    {% if form.custom_fields %}
+                      <div class="field-group mb-5">
+                        <div class="row mb-2">
+                          <h5 class="offset-sm-3">Custom Fields</h5>
+                        </div>
+                        {% render_custom_fields form %}
+                      </div>
+                    {% endif %}
+
+                    {# Render comments #}
+                    {% if form.comments %}
+                      <div class="field-group mb-5">
+                        <div class="row mb-2">
+                          <h5 class="offset-sm-3">Comments</h5>
+                        </div>
+                        {% render_field form.comments bulk_nullable=True %}
+                      </div>
+                    {% endif %}
+
+                  {% else %}
+
+                    {# Render all fields #}
+                    {% for field in form.visible_fields %}
+                      {% if field.name in form.nullable_fields %}
+                        {% render_field field bulk_nullable=True %}
+                      {% else %}
+                        {% render_field field %}
+                      {% endif %}
+                    {% endfor %}
+
+                  {% endif %}
                 </div>
               </div>
 

+ 12 - 0
netbox/tenancy/forms/bulk_edit.py

@@ -38,6 +38,9 @@ class TenantBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Tenant
+    fieldsets = (
+        (None, ('group',)),
+    )
     nullable_fields = ('group',)
 
 
@@ -56,6 +59,9 @@ class ContactGroupBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = ContactGroup
+    fieldsets = (
+        (None, ('parent', 'description')),
+    )
     nullable_fields = ('parent', 'description')
 
 
@@ -66,6 +72,9 @@ class ContactRoleBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = ContactRole
+    fieldsets = (
+        (None, ('description',)),
+    )
     nullable_fields = ('description',)
 
 
@@ -91,4 +100,7 @@ class ContactBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Contact
+    fieldsets = (
+        (None, ('group', 'title', 'phone', 'email', 'address')),
+    )
     nullable_fields = ('group', 'title', 'phone', 'email', 'address', 'comments')

+ 19 - 0
netbox/virtualization/forms/bulk_edit.py

@@ -30,6 +30,9 @@ class ClusterTypeBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = ClusterType
+    fieldsets = (
+        (None, ('description',)),
+    )
     nullable_fields = ('description',)
 
 
@@ -40,6 +43,9 @@ class ClusterGroupBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = ClusterGroup
+    fieldsets = (
+        (None, ('description',)),
+    )
     nullable_fields = ('description',)
 
 
@@ -78,6 +84,10 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = Cluster
+    fieldsets = (
+        (None, ('type', 'group', 'tenant',)),
+        ('Site', ('region', 'site_group', 'site',)),
+    )
     nullable_fields = (
         'group', 'site', 'comments', 'tenant',
     )
@@ -129,6 +139,10 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = VirtualMachine
+    fieldsets = (
+        (None, ('cluster', 'status', 'role', 'tenant', 'platform')),
+        ('Resources', ('vcpus', 'memory', 'disk'))
+    )
     nullable_fields = (
         'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments',
     )
@@ -178,6 +192,11 @@ class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = VMInterface
+    fieldsets = (
+        (None, ('mtu', 'enabled', 'description')),
+        ('Related Interfaces', ('parent', 'bridge')),
+        ('802.1Q Switching', ('mode', 'untagged_vlan', 'tagged_vlans')),
+    )
     nullable_fields = (
         'parent', 'bridge', 'mtu', 'description',
     )

+ 11 - 0
netbox/wireless/forms/bulk_edit.py

@@ -26,6 +26,9 @@ class WirelessLANGroupBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = WirelessLANGroup
+    fieldsets = (
+        (None, ('parent', 'description')),
+    )
     nullable_fields = ('parent', 'description')
 
 
@@ -61,6 +64,10 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = WirelessLAN
+    fieldsets = (
+        (None, ('group', 'vlan', 'ssid', 'description')),
+        ('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')),
+    )
     nullable_fields = (
         'ssid', 'group', 'vlan', 'description', 'auth_type', 'auth_cipher', 'auth_psk',
     )
@@ -93,6 +100,10 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
     )
 
     model = WirelessLink
+    fieldsets = (
+        (None, ('ssid', 'status', 'description')),
+        ('Authentication', ('auth_type', 'auth_cipher', 'auth_psk'))
+    )
     nullable_fields = (
         'ssid', 'description', 'auth_type', 'auth_cipher', 'auth_psk',
     )