فهرست منبع

Introduce InlineFields for rendering fields side-by-side

Jeremy Stretch 1 سال پیش
والد
کامیت
f585c36d86

+ 17 - 0
netbox/dcim/forms/model_forms.py

@@ -16,6 +16,7 @@ from utilities.forms.fields import (
     CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField,
     CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField,
     NumericArrayField, SlugField,
     NumericArrayField, SlugField,
 )
 )
+from utilities.forms.rendering import InlineFields
 from utilities.forms.widgets import APISelect, ClearableFileInput, HTMXSelect, NumberWithOptions, SelectWithPK
 from utilities.forms.widgets import APISelect, ClearableFileInput, HTMXSelect, NumberWithOptions, SelectWithPK
 from virtualization.models import Cluster
 from virtualization.models import Cluster
 from wireless.models import WirelessLAN, WirelessLANGroup
 from wireless.models import WirelessLAN, WirelessLANGroup
@@ -227,6 +228,22 @@ class RackForm(TenancyForm, NetBoxModelForm):
     )
     )
     comments = CommentField()
     comments = CommentField()
 
 
+    fieldsets = (
+        (_('Rack'), ('site', 'location', 'name', 'status', 'role', 'description', 'tags')),
+        (_('Inventory Control'), ('facility_id', 'serial', 'asset_tag')),
+        (_('Tenancy'), ('tenant_group', 'tenant')),
+        (_('Dimensions'), (
+            'type',
+            'width',
+            'starting_unit',
+            'u_height',
+            InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
+            InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
+            'mounting_depth',
+            'desc_units',
+        )),
+    )
+
     class Meta:
     class Meta:
         model = Rack
         model = Rack
         fields = [
         fields = [

+ 0 - 1
netbox/dcim/views.py

@@ -727,7 +727,6 @@ class RackNonRackedView(generic.ObjectChildrenView):
 class RackEditView(generic.ObjectEditView):
 class RackEditView(generic.ObjectEditView):
     queryset = Rack.objects.all()
     queryset = Rack.objects.all()
     form = forms.RackForm
     form = forms.RackForm
-    template_name = 'dcim/rack_edit.html'
 
 
 
 
 @register_model_view(Rack, 'delete')
 @register_model_view(Rack, 'delete')

+ 0 - 90
netbox/templates/dcim/rack_edit.html

@@ -1,90 +0,0 @@
-{% extends 'generic/object_edit.html' %}
-{% load form_helpers %}
-{% load i18n %}
-
-{% block form %}
-    <div class="field-group my-5">
-        <div class="row">
-          <h5 class="col-9 offset-3">{% trans "Rack" %}</h5>
-        </div>
-        {% render_field form.site %}
-        {% render_field form.location %}
-        {% render_field form.name %}
-        {% render_field form.status %}
-        {% render_field form.role %}
-        {% render_field form.description %}
-        {% render_field form.tags %}
-    </div>
-
-    <div class="field-group my-5">
-        <div class="row">
-          <h5 class="col-9 offset-3">{% trans "Inventory Control" %}</h5>
-        </div>
-        {% render_field form.facility_id %}
-        {% render_field form.serial %}
-        {% render_field form.asset_tag %}
-    </div>
-
-    <div class="field-group my-5">
-        <div class="row">
-          <h5 class="col-9 offset-3">{% trans "Tenancy" %}</h5>
-        </div>
-        {% render_field form.tenant_group %}
-        {% render_field form.tenant %}
-    </div>
-
-    <div class="field-group my-5">
-        <div class="row">
-          <h5 class="col-9 offset-3">{% trans "Dimensions" %}</h5>
-        </div>
-        {% render_field form.type %}
-        {% render_field form.width %}
-        {% render_field form.starting_unit %}
-        {% render_field form.u_height %}
-        <div class="row mb-3">
-            <label class="col col-md-3 col-form-label text-lg-end">{% trans "Outer Dimensions" %}</label>
-            <div class="col col-md-3 mb-1">
-                {{ form.outer_width }}
-                <div class="form-text">{% trans "Width" %}</div>
-            </div>
-            <div class="col col-md-3 mb-1">
-                {{ form.outer_depth }}
-                <div class="form-text">{% trans "Depth" %}</div>
-            </div>
-            <div class="col col-md-3 mb-1">
-                {{ form.outer_unit }}
-                <div class="form-text">{% trans "Unit" %}</div>
-            </div>
-        </div>
-        <div class="row mb-3">
-            <label class="col col-md-3 col-form-label text-lg-end">{% trans "Weight" %}</label>
-            <div class="col col-md-3 mb-1">
-                {{ form.weight }}
-                <div class="form-text">{% trans "Weight" %}</div>
-            </div>
-            <div class="col col-md-3 mb-1">
-                {{ form.max_weight }}
-                <div class="form-text">{% trans "Maximum Weight" %}</div>
-            </div>
-            <div class="col col-md-3 mb-1">
-                {{ form.weight_unit }}
-                <div class="form-text">{% trans "Unit" %}</div>
-            </div>
-        </div>
-        {% render_field form.mounting_depth %}
-        {% render_field form.desc_units %}
-    </div>
-
-    {% if form.custom_fields %}
-      <div class="field-group my-5">
-        <div class="row">
-          <h5 class="col-9 offset-3">{% trans "Custom Fields" %}</h5>
-        </div>
-          {% render_custom_fields form %}
-      </div>
-    {% endif %}
-
-    <div class="field-group my-5">
-      {% render_field form.comments %}
-    </div>
-{% endblock %}

+ 2 - 15
netbox/templates/htmx/form.html

@@ -9,21 +9,8 @@
   {% endfor %}
   {% endfor %}
 
 
   {# Render grouped fields according to Form #}
   {# Render grouped fields according to Form #}
-  {% for group, fields in form.fieldsets %}
-    <div class="field-group mb-5">
-      {% if group %}
-        <div class="row">
-          <h5 class="col-9 offset-3">{{ group }}</h5>
-        </div>
-      {% endif %}
-      {% for name in fields %}
-        {% with field=form|getfield:name %}
-          {% if field and not field.field.widget.is_hidden %}
-            {% render_field field %}
-          {% endif %}
-        {% endwith %}
-      {% endfor %}
-    </div>
+  {% for group, items in form.fieldsets %}
+    {% render_fieldset form items heading=group %}
   {% endfor %}
   {% endfor %}
 
 
   {% if form.custom_fields %}
   {% if form.custom_fields %}

+ 10 - 0
netbox/utilities/forms/rendering.py

@@ -0,0 +1,10 @@
+__all__ = (
+    'InlineFields',
+)
+
+
+class InlineFields:
+
+    def __init__(self, *field_names, label=None):
+        self.field_names = field_names
+        self.label = label

+ 26 - 0
netbox/utilities/templates/form_helpers/render_fieldset.html

@@ -0,0 +1,26 @@
+{% load i18n %}
+{% load form_helpers %}
+<div class="field-group mb-5">
+  {% if heading %}
+    <div class="row">
+      <h5 class="col-9 offset-3">{{ heading }}</h5>
+    </div>
+  {% endif %}
+  {% for layout, title, items in rows %}
+    {% if layout == 'field' %}
+      {# Single form field #}
+      {% render_field items.0 %}
+    {% elif layout == 'inline' %}
+      {# Multiple form fields on the same line #}
+      <div class="row mb-3">
+        <label class="col col-form-label text-lg-end">{{ title|default:'' }}</label>
+        {% for field in items %}
+          <div class="col mb-1">
+            {{ field }}
+            <div class="form-text">{% trans field.label %}</div>
+          </div>
+        {% endfor %}
+      </div>
+    {% endif %}
+  {% endfor %}
+</div>

+ 24 - 0
netbox/utilities/templatetags/form_helpers.py

@@ -1,5 +1,7 @@
 from django import template
 from django import template
 
 
+from utilities.forms.rendering import InlineFields
+
 __all__ = (
 __all__ = (
     'getfield',
     'getfield',
     'render_custom_fields',
     'render_custom_fields',
@@ -45,6 +47,28 @@ def widget_type(field):
 # Inclusion tags
 # Inclusion tags
 #
 #
 
 
+@register.inclusion_tag('form_helpers/render_fieldset.html')
+def render_fieldset(form, fieldset, heading=None):
+    """
+    Render a group set of fields.
+    """
+    rows = []
+    for item in fieldset:
+        if type(item) is InlineFields:
+            rows.append(
+                ('inline', item.label, [form[name] for name in item.field_names])
+            )
+        else:
+            rows.append(
+                ('field', None, [form[item]])
+            )
+
+    return {
+        'heading': heading,
+        'rows': rows,
+    }
+
+
 @register.inclusion_tag('form_helpers/render_field.html')
 @register.inclusion_tag('form_helpers/render_field.html')
 def render_field(field, bulk_nullable=False, label=None):
 def render_field(field, bulk_nullable=False, label=None):
     """
     """