mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-19 03:42:25 -06:00
Refactor form rendering components & add docstrings
This commit is contained in:
@@ -3,28 +3,39 @@ import string
|
||||
from functools import cached_property
|
||||
|
||||
__all__ = (
|
||||
'FieldSet',
|
||||
'InlineFields',
|
||||
'ObjectAttribute',
|
||||
'TabbedFieldGroups',
|
||||
'TabbedGroups',
|
||||
)
|
||||
|
||||
|
||||
class FieldGroup:
|
||||
class FieldSet:
|
||||
"""
|
||||
A generic grouping of fields, with an optional name. Each field will be rendered
|
||||
on its own row under the heading (name).
|
||||
"""
|
||||
def __init__(self, *fields, name=None):
|
||||
self.fields = fields
|
||||
self.name = name
|
||||
|
||||
def __init__(self, label, *field_names):
|
||||
self.field_names = field_names
|
||||
|
||||
class InlineFields:
|
||||
"""
|
||||
A set of fields rendered inline (side-by-side) with a shared label; typically nested within a FieldSet.
|
||||
"""
|
||||
def __init__(self, *fields, label=None):
|
||||
self.fields = fields
|
||||
self.label = label
|
||||
|
||||
|
||||
class InlineFields(FieldGroup):
|
||||
pass
|
||||
|
||||
|
||||
class TabbedFieldGroups:
|
||||
|
||||
class TabbedGroups:
|
||||
"""
|
||||
Two or more groups of fields (FieldSets) arranged under tabs among which the user can navigate.
|
||||
"""
|
||||
def __init__(self, *groups):
|
||||
self.groups = [
|
||||
FieldGroup(*group) for group in groups
|
||||
FieldSet(*group, name=name) for name, *group in groups
|
||||
]
|
||||
|
||||
# Initialize a random ID for the group (for tab selection)
|
||||
@@ -37,13 +48,15 @@ class TabbedFieldGroups:
|
||||
return [
|
||||
{
|
||||
'id': f'{self.id}_{i}',
|
||||
'title': group.label,
|
||||
'fields': group.field_names,
|
||||
'title': group.name,
|
||||
'fields': group.fields,
|
||||
} for i, group in enumerate(self.groups, start=1)
|
||||
]
|
||||
|
||||
|
||||
class ObjectAttribute:
|
||||
|
||||
"""
|
||||
Renders the value for a specific attribute on the form's instance.
|
||||
"""
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from django import template
|
||||
|
||||
from utilities.forms.rendering import InlineFields, ObjectAttribute, TabbedFieldGroups
|
||||
from utilities.forms.rendering import FieldSet, InlineFields, ObjectAttribute, TabbedGroups
|
||||
|
||||
__all__ = (
|
||||
'getfield',
|
||||
@@ -48,24 +48,29 @@ def widget_type(field):
|
||||
#
|
||||
|
||||
@register.inclusion_tag('form_helpers/render_fieldset.html')
|
||||
def render_fieldset(form, fieldset, heading=None):
|
||||
def render_fieldset(form, fieldset):
|
||||
"""
|
||||
Render a group set of fields.
|
||||
"""
|
||||
# Handle legacy tuple-based fieldset definitions, e.g. (_('Label'), ('field1, 'field2', 'field3'))
|
||||
if type(fieldset) is not FieldSet:
|
||||
name, fields = fieldset
|
||||
fieldset = FieldSet(*fields, name=name)
|
||||
|
||||
rows = []
|
||||
for item in fieldset:
|
||||
for item in fieldset.fields:
|
||||
|
||||
# Multiple fields side-by-side
|
||||
if type(item) is InlineFields:
|
||||
fields = [
|
||||
form[name] for name in item.field_names if name in form.fields
|
||||
form[name] for name in item.fields if name in form.fields
|
||||
]
|
||||
rows.append(
|
||||
('inline', item.label, fields)
|
||||
)
|
||||
|
||||
# Tabbed groups of fields
|
||||
elif type(item) is TabbedFieldGroups:
|
||||
elif type(item) is TabbedGroups:
|
||||
tabs = [
|
||||
{
|
||||
'id': tab['id'],
|
||||
@@ -95,7 +100,7 @@ def render_fieldset(form, fieldset, heading=None):
|
||||
)
|
||||
|
||||
return {
|
||||
'heading': heading,
|
||||
'heading': fieldset.name,
|
||||
'rows': rows,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user