From 32edb8dfe6cbfbbc037a45b11bf46486800055c9 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 19 Mar 2024 09:20:49 -0400 Subject: [PATCH] Misc cleanup & documentation for FieldSets --- netbox/utilities/forms/rendering.py | 39 +++++++++++++++---- netbox/utilities/templatetags/form_helpers.py | 2 +- netbox/vpn/forms/filtersets.py | 2 +- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/netbox/utilities/forms/rendering.py b/netbox/utilities/forms/rendering.py index 0d9344131..723e911e6 100644 --- a/netbox/utilities/forms/rendering.py +++ b/netbox/utilities/forms/rendering.py @@ -12,17 +12,31 @@ __all__ = ( class FieldSet: """ - A generic grouping of fields, with an optional name. Each field will be rendered - on its own row under the heading (name). + A generic grouping of fields, with an optional name. Each item will be rendered + on its own row under the provided heading (name), if any. The following types + may be passed as items: + + * Field name (string) + * InlineFields instance + * TabbedGroups instance + * ObjectAttribute instance + + Parameters: + items: An iterable of items to be rendered (one per row) + name: The fieldset's name, displayed as a heading (optional) """ - def __init__(self, *fields, name=None): - self.fields = fields + def __init__(self, *items, name=None): + self.items = items self.name = name class InlineFields: """ - A set of fields rendered inline (side-by-side) with a shared label; typically nested within a FieldSet. + A set of fields rendered inline (side-by-side) with a shared label. + + Parameters: + fields: An iterable of form field names + label: The label text to render for the row (optional) """ def __init__(self, *fields, label=None): self.fields = fields @@ -31,7 +45,11 @@ class InlineFields: class TabbedGroups: """ - Two or more groups of fields (FieldSets) arranged under tabs among which the user can navigate. + Two or more groups of fields (FieldSets) arranged under tabs among which the user can toggle. + + Parameters: + fieldsets: An iterable of FieldSet instances, one per tab. Each FieldSet *must* have a + name assigned, which will be employed as the tab's label. """ def __init__(self, *fieldsets): for fs in fieldsets: @@ -50,14 +68,19 @@ class TabbedGroups: { 'id': f'{self.id}_{i}', 'title': group.name, - 'fields': group.fields, + 'fields': group.items, } for i, group in enumerate(self.groups, start=1) ] class ObjectAttribute: """ - Renders the value for a specific attribute on the form's instance. + Renders the value for a specific attribute on the form's instance. This may be used to + display a read-only value and convey additional context to the user. If the attribute has + a `get_absolute_url()` method, it will be rendered as a hyperlink. + + Parameters: + name: The name of the attribute to be displayed """ def __init__(self, name): self.name = name diff --git a/netbox/utilities/templatetags/form_helpers.py b/netbox/utilities/templatetags/form_helpers.py index 723c5206a..e9edfed31 100644 --- a/netbox/utilities/templatetags/form_helpers.py +++ b/netbox/utilities/templatetags/form_helpers.py @@ -64,7 +64,7 @@ def render_fieldset(form, fieldset): fieldset = FieldSet(*fields, name=name) rows = [] - for item in fieldset.fields: + for item in fieldset.items: # Multiple fields side-by-side if type(item) is InlineFields: diff --git a/netbox/vpn/forms/filtersets.py b/netbox/vpn/forms/filtersets.py index d25719d06..10dc441e2 100644 --- a/netbox/vpn/forms/filtersets.py +++ b/netbox/vpn/forms/filtersets.py @@ -234,7 +234,7 @@ class L2VPNFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm): class L2VPNTerminationFilterForm(NetBoxModelFilterSetForm): model = L2VPNTermination fieldsets = ( - FieldSet('filter_id', 'l2vpn_id',), + FieldSet('filter_id', 'l2vpn_id'), FieldSet( 'assigned_object_type_id', 'region_id', 'site_id', 'device_id', 'virtual_machine_id', 'vlan_id', name=_('Assigned Object')