diff --git a/netbox_custom_objects/templates/netbox_custom_objects/customobject.html b/netbox_custom_objects/templates/netbox_custom_objects/customobject.html index b69d828..b796961 100644 --- a/netbox_custom_objects/templates/netbox_custom_objects/customobject.html +++ b/netbox_custom_objects/templates/netbox_custom_objects/customobject.html @@ -102,19 +102,26 @@ {% endif %} - {% for field in fields %} - {% with is_visible_in_ui=object|get_field_is_ui_visible:field %} - {% if field.is_single_value and is_visible_in_ui %} - - {{ field }} - - {% with customfield=field value=object|get_field_value:field %} - {% include "builtins/customfield_value.html" %} - {% endwith %} - - - {% endif %} - {% endwith %} + {% for group_name, group_fields in field_groups.items %} + {% if group_name %} + + {{ group_name }} + + {% endif %} + {% for field in group_fields %} + {% with is_visible_in_ui=object|get_field_is_ui_visible:field %} + {% if field.is_single_value and is_visible_in_ui %} + + {{ field }} + + {% with customfield=field value=object|get_field_value:field %} + {% include "builtins/customfield_value.html" %} + {% endwith %} + + + {% endif %} + {% endwith %} + {% endfor %} {% endfor %} @@ -123,12 +130,15 @@
{% include 'inc/panels/tags.html' %} {% plugin_right_page object %} - {% for field in fields %} + {% for group_name, group_fields in field_groups.items %} + {% for field in group_fields %} {% if field.many %} {% with field_values=object|get_child_relations:field is_visible_in_ui=object|get_field_is_ui_visible:field %} {% if is_visible_in_ui %}
-

{{ field }}

+

+ {% if group_name %}{{ group_name }}: {% endif %}{{ field }} +

{% for relation in field_values.all %} @@ -140,6 +150,7 @@

{{ field }}

{% endif %} {% endwith %} {% endif %} + {% endfor %} {% endfor %} diff --git a/netbox_custom_objects/views.py b/netbox_custom_objects/views.py index 8a81acf..bcec4ff 100644 --- a/netbox_custom_objects/views.py +++ b/netbox_custom_objects/views.py @@ -18,8 +18,12 @@ from netbox.views.generic.mixins import TableMixin from utilities.forms import ConfirmationForm from utilities.htmx import htmx_partial -from utilities.views import (ConditionalLoginRequiredMixin, ViewTab, - get_viewname, register_model_view) +from utilities.views import ( + ConditionalLoginRequiredMixin, + ViewTab, + get_viewname, + register_model_view, +) from netbox_custom_objects.tables import CustomObjectTable @@ -33,7 +37,7 @@ class CustomJournalEntryForm(JournalEntryForm): """ def __init__(self, *args, **kwargs): - self.custom_object = kwargs.pop('custom_object', None) + self.custom_object = kwargs.pop("custom_object", None) super().__init__(*args, **kwargs) def get_return_url(self): @@ -41,10 +45,13 @@ def get_return_url(self): Override to return the correct URL for custom objects. """ if self.custom_object: - return reverse('plugins:netbox_custom_objects:customobject_journal', kwargs={ - 'custom_object_type': self.custom_object.custom_object_type.name, - 'pk': self.custom_object.pk - }) + return reverse( + "plugins:netbox_custom_objects:customobject_journal", + kwargs={ + "custom_object_type": self.custom_object.custom_object_type.name, + "pk": self.custom_object.pk, + }, + ) return super().get_return_url() @@ -52,6 +59,7 @@ class CustomJournalEntryEditView(generic.ObjectEditView): """ Custom journal entry edit view that handles return URLs for custom objects. """ + queryset = JournalEntry.objects.all() form = CustomJournalEntryForm @@ -59,18 +67,23 @@ def get_return_url(self, request, instance): """ Override to return the correct URL for custom objects. """ - if instance.assigned_object and hasattr(instance.assigned_object, 'custom_object_type'): + if instance.assigned_object and hasattr( + instance.assigned_object, "custom_object_type" + ): # This is a custom object - return reverse('plugins:netbox_custom_objects:customobject_journal', kwargs={ - 'custom_object_type': instance.assigned_object.custom_object_type.name, - 'pk': instance.assigned_object.pk - }) + return reverse( + "plugins:netbox_custom_objects:customobject_journal", + kwargs={ + "custom_object_type": instance.assigned_object.custom_object_type.name, + "pk": instance.assigned_object.pk, + }, + ) # Fall back to standard behavior for non-custom objects if not instance.assigned_object: - return reverse('extras:journalentry_list') + return reverse("extras:journalentry_list") obj = instance.assigned_object - viewname = get_viewname(obj, 'journal') - return reverse(viewname, kwargs={'pk': obj.pk}) + viewname = get_viewname(obj, "journal") + return reverse(viewname, kwargs={"pk": obj.pk}) class CustomObjectTableMixin(TableMixin): @@ -391,9 +404,21 @@ def get_object(self, **kwargs): return get_object_or_404(model.objects.all(), **lookup_kwargs) def get_extra_context(self, request, instance): - fields = instance.custom_object_type.fields.all().order_by("weight") + fields = instance.custom_object_type.fields.all().order_by( + "group_name", "weight", "name" + ) + + # Group fields by group_name + field_groups = {} + for field in fields: + group_name = field.group_name or None # Use None for ungrouped fields + if group_name not in field_groups: + field_groups[group_name] = [] + field_groups[group_name].append(field) + return { "fields": fields, + "field_groups": field_groups, } @@ -631,7 +656,7 @@ def get(self, request, custom_object_type, **kwargs): initial={ "assigned_object_type": content_type, "assigned_object_id": obj.pk, - } + }, ) else: form = None @@ -649,7 +674,9 @@ def get(self, request, custom_object_type, **kwargs): "table": journal_table, "base_template": self.base_template, "tab": "journal", - "form_action": reverse('plugins:netbox_custom_objects:custom_journalentry_add'), + "form_action": reverse( + "plugins:netbox_custom_objects:custom_journalentry_add" + ), }, )