Przeglądaj źródła

Merge pull request #20951 from netbox-community/20925-comments-oranizationalmodel

Add comments to OrganizationalModel
bctiemann 2 miesięcy temu
rodzic
commit
3140060f21
67 zmienionych plików z 283 dodań i 82 usunięć
  1. 3 3
      netbox/circuits/api/serializers_/circuits.py
  2. 3 3
      netbox/circuits/forms/bulk_edit.py
  3. 3 3
      netbox/circuits/forms/bulk_import.py
  4. 3 3
      netbox/circuits/forms/model_forms.py
  5. 28 0
      netbox/circuits/migrations/0055_add_comments_to_organizationalmodel.py
  6. 3 0
      netbox/circuits/search.py
  7. 3 3
      netbox/circuits/tables/circuits.py
  8. 3 2
      netbox/dcim/api/serializers_/manufacturers.py
  9. 1 1
      netbox/dcim/api/serializers_/racks.py
  10. 1 1
      netbox/dcim/api/serializers_/roles.py
  11. 3 3
      netbox/dcim/forms/bulk_edit.py
  12. 3 3
      netbox/dcim/forms/bulk_import.py
  13. 3 3
      netbox/dcim/forms/model_forms.py
  14. 28 0
      netbox/dcim/migrations/0224_add_comments_to_organizationalmodel.py
  15. 14 0
      netbox/dcim/search.py
  16. 1 1
      netbox/dcim/tables/devices.py
  17. 2 1
      netbox/dcim/tables/devicetypes.py
  18. 1 1
      netbox/dcim/tables/racks.py
  19. 2 1
      netbox/dcim/views.py
  20. 3 3
      netbox/ipam/api/serializers_/asns.py
  21. 1 1
      netbox/ipam/api/serializers_/roles.py
  22. 2 2
      netbox/ipam/api/serializers_/vlans.py
  23. 4 4
      netbox/ipam/forms/bulk_edit.py
  24. 6 4
      netbox/ipam/forms/bulk_import.py
  25. 5 4
      netbox/ipam/forms/model_forms.py
  26. 33 0
      netbox/ipam/migrations/0085_add_comments_to_organizationalmodel.py
  27. 4 0
      netbox/ipam/search.py
  28. 2 2
      netbox/ipam/tables/asn.py
  29. 3 3
      netbox/ipam/tables/ip.py
  30. 1 1
      netbox/ipam/tables/vlans.py
  31. 1 0
      netbox/netbox/forms/bulk_edit.py
  32. 1 0
      netbox/netbox/forms/model_forms.py
  33. 1 0
      netbox/netbox/graphql/filters.py
  34. 4 0
      netbox/netbox/models/__init__.py
  35. 3 0
      netbox/netbox/tables/tables.py
  36. 1 0
      netbox/templates/circuits/circuittype.html
  37. 1 0
      netbox/templates/circuits/virtualcircuittype.html
  38. 1 0
      netbox/templates/dcim/inventoryitemrole.html
  39. 1 0
      netbox/templates/ipam/asnrange.html
  40. 1 0
      netbox/templates/ipam/rir.html
  41. 1 0
      netbox/templates/ipam/role.html
  42. 1 0
      netbox/templates/ipam/vlangroup.html
  43. 1 0
      netbox/templates/tenancy/contactrole.html
  44. 1 0
      netbox/templates/virtualization/clustergroup.html
  45. 1 0
      netbox/templates/virtualization/clustertype.html
  46. 1 0
      netbox/templates/vpn/tunnelgroup.html
  47. 2 2
      netbox/tenancy/api/serializers_/contacts.py
  48. 1 1
      netbox/tenancy/forms/bulk_edit.py
  49. 1 1
      netbox/tenancy/forms/bulk_import.py
  50. 1 1
      netbox/tenancy/forms/model_forms.py
  51. 18 0
      netbox/tenancy/migrations/0022_add_comments_to_organizationalmodel.py
  52. 1 0
      netbox/tenancy/search.py
  53. 1 1
      netbox/tenancy/tables/contacts.py
  54. 4 4
      netbox/virtualization/api/serializers_/clusters.py
  55. 2 2
      netbox/virtualization/forms/bulk_edit.py
  56. 2 2
      netbox/virtualization/forms/bulk_import.py
  57. 2 2
      netbox/virtualization/forms/model_forms.py
  58. 23 0
      netbox/virtualization/migrations/0051_add_comments_to_organizationalmodel.py
  59. 2 0
      netbox/virtualization/search.py
  60. 4 3
      netbox/virtualization/tables/clusters.py
  61. 2 2
      netbox/vpn/api/serializers_/tunnels.py
  62. 1 1
      netbox/vpn/forms/bulk_edit.py
  63. 1 1
      netbox/vpn/forms/bulk_import.py
  64. 1 1
      netbox/vpn/forms/model_forms.py
  65. 18 0
      netbox/vpn/migrations/0011_add_comments_to_organizationalmodel.py
  66. 1 0
      netbox/vpn/search.py
  67. 2 2
      netbox/vpn/tables/tunnels.py

+ 3 - 3
netbox/circuits/api/serializers_/circuits.py

@@ -38,7 +38,7 @@ class CircuitTypeSerializer(OrganizationalModelSerializer):
     class Meta:
         model = CircuitType
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'color', 'description', 'owner', 'tags',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'color', 'description', 'owner', 'comments', 'tags',
             'custom_fields', 'created', 'last_updated', 'circuit_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'circuit_count')
@@ -71,7 +71,7 @@ class CircuitGroupSerializer(OrganizationalModelSerializer):
     class Meta:
         model = CircuitGroup
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'tenant', 'owner', 'tags',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'tenant', 'owner', 'comments', 'tags',
             'custom_fields', 'created', 'last_updated', 'circuit_count'
         ]
         brief_fields = ('id', 'url', 'display', 'name')
@@ -161,7 +161,7 @@ class VirtualCircuitTypeSerializer(OrganizationalModelSerializer):
     class Meta:
         model = VirtualCircuitType
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'color', 'description', 'owner', 'tags',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'color', 'description', 'owner', 'comments', 'tags',
             'custom_fields', 'created', 'last_updated', 'virtual_circuit_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'virtual_circuit_count')

+ 3 - 3
netbox/circuits/forms/bulk_edit.py

@@ -99,7 +99,7 @@ class CircuitTypeBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('color', 'description'),
     )
-    nullable_fields = ('color', 'description')
+    nullable_fields = ('color', 'description', 'comments')
 
 
 class CircuitBulkEditForm(PrimaryModelBulkEditForm):
@@ -241,7 +241,7 @@ class CircuitGroupBulkEditForm(OrganizationalModelBulkEditForm):
 
     model = CircuitGroup
     nullable_fields = (
-        'description', 'tenant',
+        'description', 'tenant', 'comments',
     )
 
 
@@ -274,7 +274,7 @@ class VirtualCircuitTypeBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('color', 'description'),
     )
-    nullable_fields = ('color', 'description')
+    nullable_fields = ('color', 'description', 'comments')
 
 
 class VirtualCircuitBulkEditForm(PrimaryModelBulkEditForm):

+ 3 - 3
netbox/circuits/forms/bulk_import.py

@@ -73,7 +73,7 @@ class CircuitTypeImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = CircuitType
-        fields = ('name', 'slug', 'color', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'color', 'description', 'owner', 'comments', 'tags')
 
 
 class CircuitImportForm(PrimaryModelImportForm):
@@ -176,7 +176,7 @@ class CircuitGroupImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = CircuitGroup
-        fields = ('name', 'slug', 'description', 'tenant', 'owner', 'tags')
+        fields = ('name', 'slug', 'description', 'tenant', 'owner', 'comments', 'tags')
 
 
 class CircuitGroupAssignmentImportForm(NetBoxModelImportForm):
@@ -199,7 +199,7 @@ class VirtualCircuitTypeImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = VirtualCircuitType
-        fields = ('name', 'slug', 'color', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'color', 'description', 'owner', 'comments', 'tags')
 
 
 class VirtualCircuitImportForm(PrimaryModelImportForm):

+ 3 - 3
netbox/circuits/forms/model_forms.py

@@ -97,7 +97,7 @@ class CircuitTypeForm(OrganizationalModelForm):
     class Meta:
         model = CircuitType
         fields = [
-            'name', 'slug', 'color', 'description', 'tags',
+            'name', 'slug', 'color', 'description', 'comments', 'tags',
         ]
 
 
@@ -236,7 +236,7 @@ class CircuitGroupForm(TenancyForm, OrganizationalModelForm):
     class Meta:
         model = CircuitGroup
         fields = [
-            'name', 'slug', 'description', 'tenant_group', 'tenant', 'owner', 'tags',
+            'name', 'slug', 'description', 'tenant_group', 'tenant', 'owner', 'comments', 'tags',
         ]
 
 
@@ -307,7 +307,7 @@ class VirtualCircuitTypeForm(OrganizationalModelForm):
     class Meta:
         model = VirtualCircuitType
         fields = [
-            'name', 'slug', 'color', 'description', 'owner', 'tags',
+            'name', 'slug', 'color', 'description', 'owner', 'comments', 'tags',
         ]
 
 

+ 28 - 0
netbox/circuits/migrations/0055_add_comments_to_organizationalmodel.py

@@ -0,0 +1,28 @@
+# Generated by Django 5.2.8 on 2025-12-08 17:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('circuits', '0054_cable_position'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='circuitgroup',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AddField(
+            model_name='circuittype',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AddField(
+            model_name='virtualcircuittype',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+    ]

+ 3 - 0
netbox/circuits/search.py

@@ -20,6 +20,7 @@ class CircuitGroupIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)
 
@@ -44,6 +45,7 @@ class CircuitTypeIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)
 
@@ -109,5 +111,6 @@ class VirtualCircuitTypeIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)

+ 3 - 3
netbox/circuits/tables/circuits.py

@@ -40,8 +40,8 @@ class CircuitTypeTable(OrganizationalModelTable):
     class Meta(OrganizationalModelTable.Meta):
         model = CircuitType
         fields = (
-            'pk', 'id', 'name', 'circuit_count', 'color', 'description', 'slug', 'tags', 'created', 'last_updated',
-            'actions',
+            'pk', 'id', 'name', 'circuit_count', 'color', 'description', 'slug', 'comments', 'tags', 'created',
+            'last_updated', 'actions',
         )
         default_columns = ('pk', 'name', 'circuit_count', 'color', 'description')
 
@@ -175,7 +175,7 @@ class CircuitGroupTable(OrganizationalModelTable):
     class Meta(OrganizationalModelTable.Meta):
         model = CircuitGroup
         fields = (
-            'pk', 'name', 'description', 'circuit_group_assignment_count', 'tags',
+            'pk', 'name', 'description', 'circuit_group_assignment_count', 'comments', 'tags',
             'created', 'last_updated', 'actions',
         )
         default_columns = ('pk', 'name', 'description', 'circuit_group_assignment_count')

+ 3 - 2
netbox/dcim/api/serializers_/manufacturers.py

@@ -18,7 +18,8 @@ class ManufacturerSerializer(OrganizationalModelSerializer):
     class Meta:
         model = Manufacturer
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'tags', 'custom_fields',
-            'created', 'last_updated', 'devicetype_count', 'moduletype_count', 'inventoryitem_count', 'platform_count',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'comments', 'tags',
+            'custom_fields', 'created', 'last_updated', 'devicetype_count', 'moduletype_count', 'inventoryitem_count',
+            'platform_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'devicetype_count')

+ 1 - 1
netbox/dcim/api/serializers_/racks.py

@@ -30,7 +30,7 @@ class RackRoleSerializer(OrganizationalModelSerializer):
     class Meta:
         model = RackRole
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'color', 'description', 'owner', 'tags',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'color', 'description', 'owner', 'comments', 'tags',
             'custom_fields', 'created', 'last_updated', 'rack_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'rack_count')

+ 1 - 1
netbox/dcim/api/serializers_/roles.py

@@ -38,7 +38,7 @@ class InventoryItemRoleSerializer(OrganizationalModelSerializer):
     class Meta:
         model = InventoryItemRole
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'color', 'description', 'owner', 'tags',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'color', 'description', 'owner', 'comments', 'tags',
             'custom_fields', 'created', 'last_updated', 'inventoryitem_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'inventoryitem_count')

+ 3 - 3
netbox/dcim/forms/bulk_edit.py

@@ -208,7 +208,7 @@ class RackRoleBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('color', 'description'),
     )
-    nullable_fields = ('color', 'description')
+    nullable_fields = ('color', 'description', 'comments')
 
 
 class RackTypeBulkEditForm(PrimaryModelBulkEditForm):
@@ -474,7 +474,7 @@ class ManufacturerBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('description'),
     )
-    nullable_fields = ('description',)
+    nullable_fields = ('description', 'comments')
 
 
 class DeviceTypeBulkEditForm(PrimaryModelBulkEditForm):
@@ -1719,7 +1719,7 @@ class InventoryItemRoleBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('color', 'description'),
     )
-    nullable_fields = ('color', 'description')
+    nullable_fields = ('color', 'description', 'comments')
 
 
 class VirtualDeviceContextBulkEditForm(PrimaryModelBulkEditForm):

+ 3 - 3
netbox/dcim/forms/bulk_import.py

@@ -183,7 +183,7 @@ class RackRoleImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = RackRole
-        fields = ('name', 'slug', 'color', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'color', 'description', 'owner', 'comments', 'tags')
 
 
 class RackTypeImportForm(PrimaryModelImportForm):
@@ -400,7 +400,7 @@ class ManufacturerImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = Manufacturer
-        fields = ('name', 'slug', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'description', 'owner', 'comments', 'tags')
 
 
 class DeviceTypeImportForm(PrimaryModelImportForm):
@@ -1298,7 +1298,7 @@ class InventoryItemRoleImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = InventoryItemRole
-        fields = ('name', 'slug', 'color', 'description')
+        fields = ('name', 'slug', 'color', 'description', 'owner', 'comments')
 
 
 #

+ 3 - 3
netbox/dcim/forms/model_forms.py

@@ -202,7 +202,7 @@ class RackRoleForm(OrganizationalModelForm):
     class Meta:
         model = RackRole
         fields = [
-            'name', 'slug', 'color', 'description', 'owner', 'tags',
+            'name', 'slug', 'color', 'description', 'owner', 'comments', 'tags',
         ]
 
 
@@ -345,7 +345,7 @@ class ManufacturerForm(OrganizationalModelForm):
     class Meta:
         model = Manufacturer
         fields = [
-            'name', 'slug', 'description', 'owner', 'tags',
+            'name', 'slug', 'description', 'owner', 'comments', 'tags',
         ]
 
 
@@ -1880,7 +1880,7 @@ class InventoryItemRoleForm(OrganizationalModelForm):
     class Meta:
         model = InventoryItemRole
         fields = [
-            'name', 'slug', 'color', 'description', 'owner', 'tags',
+            'name', 'slug', 'color', 'description', 'owner', 'comments', 'tags',
         ]
 
 

+ 28 - 0
netbox/dcim/migrations/0224_add_comments_to_organizationalmodel.py

@@ -0,0 +1,28 @@
+# Generated by Django 5.2.8 on 2025-12-08 17:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('dcim', '0223_frontport_positions'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='inventoryitemrole',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AddField(
+            model_name='manufacturer',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AddField(
+            model_name='rackrole',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+    ]

+ 14 - 0
netbox/dcim/search.py

@@ -137,6 +137,18 @@ class InventoryItemIndex(SearchIndex):
     display_attrs = ('device', 'manufacturer', 'parent', 'part_id', 'serial', 'asset_tag', 'description')
 
 
+@register_search
+class InventoryItemRoleIndex(SearchIndex):
+    model = models.InventoryItemRole
+    fields = (
+        ('name', 100),
+        ('slug', 110),
+        ('description', 500),
+        ('comments', 5000),
+    )
+    display_attrs = ('description',)
+
+
 @register_search
 class LocationIndex(SearchIndex):
     model = models.Location
@@ -157,6 +169,7 @@ class ManufacturerIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)
 
@@ -308,6 +321,7 @@ class RackRoleIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)
 

+ 1 - 1
netbox/dcim/tables/devices.py

@@ -1057,7 +1057,7 @@ class InventoryItemRoleTable(OrganizationalModelTable):
     class Meta(OrganizationalModelTable.Meta):
         model = models.InventoryItemRole
         fields = (
-            'pk', 'id', 'name', 'inventoryitem_count', 'color', 'description', 'slug', 'tags', 'actions',
+            'pk', 'id', 'name', 'inventoryitem_count', 'color', 'description', 'slug', 'comments', 'tags', 'actions',
         )
         default_columns = ('pk', 'name', 'inventoryitem_count', 'color', 'description')
 

+ 2 - 1
netbox/dcim/tables/devicetypes.py

@@ -64,7 +64,8 @@ class ManufacturerTable(ContactsColumnMixin, OrganizationalModelTable):
         model = models.Manufacturer
         fields = (
             'pk', 'id', 'name', 'racktype_count', 'devicetype_count', 'moduletype_count', 'inventoryitem_count',
-            'platform_count', 'description', 'slug', 'tags', 'contacts', 'actions', 'created', 'last_updated',
+            'platform_count', 'description', 'slug', 'comments', 'tags', 'contacts', 'actions', 'created',
+            'last_updated',
         )
         default_columns = (
             'pk', 'name', 'racktype_count', 'devicetype_count', 'moduletype_count', 'inventoryitem_count',

+ 1 - 1
netbox/dcim/tables/racks.py

@@ -35,7 +35,7 @@ class RackRoleTable(OrganizationalModelTable):
     class Meta(OrganizationalModelTable.Meta):
         model = RackRole
         fields = (
-            'pk', 'id', 'name', 'rack_count', 'color', 'description', 'slug', 'tags', 'actions', 'created',
+            'pk', 'id', 'name', 'rack_count', 'color', 'description', 'slug', 'comments', 'tags', 'actions', 'created',
             'last_updated',
         )
         default_columns = ('pk', 'name', 'rack_count', 'color', 'description')

+ 2 - 1
netbox/dcim/views.py

@@ -799,6 +799,7 @@ class RackRoleView(GetRelatedModelsMixin, generic.ObjectView):
         right_panels=[
             RelatedObjectsPanel(),
             CustomFieldsPanel(),
+            CommentsPanel(),
         ],
     )
 
@@ -1233,7 +1234,7 @@ class ManufacturerView(GetRelatedModelsMixin, generic.ObjectView):
     queryset = Manufacturer.objects.all()
     layout = layout.SimpleLayout(
         left_panels=[OrganizationalObjectPanel(), TagsPanel()],
-        right_panels=[RelatedObjectsPanel(), CustomFieldsPanel()],
+        right_panels=[RelatedObjectsPanel(), CustomFieldsPanel(), CommentsPanel()],
     )
 
     def get_extra_context(self, request, instance):

+ 3 - 3
netbox/ipam/api/serializers_/asns.py

@@ -21,8 +21,8 @@ class RIRSerializer(OrganizationalModelSerializer):
     class Meta:
         model = RIR
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'is_private', 'description', 'owner', 'tags',
-            'custom_fields', 'created', 'last_updated', 'aggregate_count',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'is_private', 'description', 'owner', 'comments',
+            'tags', 'custom_fields', 'created', 'last_updated', 'aggregate_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'aggregate_count')
 
@@ -36,7 +36,7 @@ class ASNRangeSerializer(OrganizationalModelSerializer):
         model = ASNRange
         fields = [
             'id', 'url', 'display_url', 'display', 'name', 'slug', 'rir', 'start', 'end', 'tenant', 'description',
-            'owner', 'tags', 'custom_fields', 'created', 'last_updated', 'asn_count',
+            'owner', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'asn_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'description')
 

+ 1 - 1
netbox/ipam/api/serializers_/roles.py

@@ -16,7 +16,7 @@ class RoleSerializer(OrganizationalModelSerializer):
     class Meta:
         model = Role
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'weight', 'description', 'owner', 'tags',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'weight', 'description', 'owner', 'comments', 'tags',
             'custom_fields', 'created', 'last_updated', 'prefix_count', 'vlan_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'prefix_count', 'vlan_count')

+ 2 - 2
netbox/ipam/api/serializers_/vlans.py

@@ -45,8 +45,8 @@ class VLANGroupSerializer(OrganizationalModelSerializer):
         model = VLANGroup
         fields = [
             'id', 'url', 'display_url', 'display', 'name', 'slug', 'scope_type', 'scope_id', 'scope', 'vid_ranges',
-            'tenant', 'description', 'owner', 'tags', 'custom_fields', 'created', 'last_updated', 'vlan_count',
-            'utilization',
+            'tenant', 'description', 'owner', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
+            'vlan_count', 'utilization',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'vlan_count')
         validators = []

+ 4 - 4
netbox/ipam/forms/bulk_edit.py

@@ -85,7 +85,7 @@ class RIRBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('is_private', 'description'),
     )
-    nullable_fields = ('is_private', 'description')
+    nullable_fields = ('is_private', 'description', 'comments')
 
 
 class ASNRangeBulkEditForm(OrganizationalModelBulkEditForm):
@@ -104,7 +104,7 @@ class ASNRangeBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('rir', 'tenant', 'description'),
     )
-    nullable_fields = ('description',)
+    nullable_fields = ('description', 'comments')
 
 
 class ASNBulkEditForm(PrimaryModelBulkEditForm):
@@ -164,7 +164,7 @@ class RoleBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('weight', 'description'),
     )
-    nullable_fields = ('description',)
+    nullable_fields = ('description', 'comments')
 
 
 class PrefixBulkEditForm(ScopedBulkEditForm, PrimaryModelBulkEditForm):
@@ -379,7 +379,7 @@ class VLANGroupBulkEditForm(OrganizationalModelBulkEditForm):
         FieldSet('scope_type', 'scope', name=_('Scope')),
         FieldSet('tenant', name=_('Tenancy')),
     )
-    nullable_fields = ('description', 'scope')
+    nullable_fields = ('description', 'scope', 'comments')
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)

+ 6 - 4
netbox/ipam/forms/bulk_import.py

@@ -84,7 +84,7 @@ class RIRImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = RIR
-        fields = ('name', 'slug', 'is_private', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'is_private', 'description', 'owner', 'comments', 'tags')
 
 
 class AggregateImportForm(PrimaryModelImportForm):
@@ -124,7 +124,7 @@ class ASNRangeImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = ASNRange
-        fields = ('name', 'slug', 'rir', 'start', 'end', 'tenant', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'rir', 'start', 'end', 'tenant', 'description', 'owner', 'comments', 'tags')
 
 
 class ASNImportForm(PrimaryModelImportForm):
@@ -151,7 +151,7 @@ class RoleImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = Role
-        fields = ('name', 'slug', 'weight', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'weight', 'description', 'owner', 'comments', 'tags')
 
 
 class PrefixImportForm(ScopedImportForm, PrimaryModelImportForm):
@@ -476,7 +476,9 @@ class VLANGroupImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = VLANGroup
-        fields = ('name', 'slug', 'scope_type', 'scope_id', 'vid_ranges', 'tenant', 'description', 'owner', 'tags')
+        fields = (
+            'name', 'slug', 'scope_type', 'scope_id', 'vid_ranges', 'tenant', 'description', 'owner', 'comments', 'tags'
+        )
         labels = {
             'scope_id': 'Scope ID',
         }

+ 5 - 4
netbox/ipam/forms/model_forms.py

@@ -99,7 +99,7 @@ class RIRForm(OrganizationalModelForm):
     class Meta:
         model = RIR
         fields = [
-            'name', 'slug', 'is_private', 'description', 'owner', 'tags',
+            'name', 'slug', 'is_private', 'description', 'owner', 'comments', 'tags',
         ]
 
 
@@ -139,7 +139,7 @@ class ASNRangeForm(TenancyForm, OrganizationalModelForm):
     class Meta:
         model = ASNRange
         fields = [
-            'name', 'slug', 'rir', 'start', 'end', 'tenant_group', 'tenant', 'owner', 'description', 'tags'
+            'name', 'slug', 'rir', 'start', 'end', 'tenant_group', 'tenant', 'owner', 'description', 'comments', 'tags'
         ]
 
 
@@ -189,7 +189,7 @@ class RoleForm(OrganizationalModelForm):
     class Meta:
         model = Role
         fields = [
-            'name', 'slug', 'weight', 'description', 'owner', 'tags',
+            'name', 'slug', 'weight', 'description', 'owner', 'comments', 'tags',
         ]
 
 
@@ -614,7 +614,8 @@ class VLANGroupForm(TenancyForm, OrganizationalModelForm):
     class Meta:
         model = VLANGroup
         fields = [
-            'name', 'slug', 'description', 'vid_ranges', 'scope_type', 'tenant_group', 'tenant', 'owner', 'tags',
+            'name', 'slug', 'description', 'vid_ranges', 'scope_type', 'tenant_group', 'tenant', 'owner', 'comments',
+            'tags',
         ]
 
     def __init__(self, *args, **kwargs):

+ 33 - 0
netbox/ipam/migrations/0085_add_comments_to_organizationalmodel.py

@@ -0,0 +1,33 @@
+# Generated by Django 5.2.8 on 2025-12-08 17:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('ipam', '0084_owner'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='asnrange',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AddField(
+            model_name='rir',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AddField(
+            model_name='role',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AddField(
+            model_name='vlangroup',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+    ]

+ 4 - 0
netbox/ipam/search.py

@@ -31,6 +31,7 @@ class ASNRangeIndex(SearchIndex):
     fields = (
         ('name', 100),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('rir', 'tenant', 'description')
 
@@ -89,6 +90,7 @@ class RIRIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)
 
@@ -100,6 +102,7 @@ class RoleIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)
 
@@ -156,6 +159,7 @@ class VLANGroupIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('scope_type', 'description')
 

+ 2 - 2
netbox/ipam/tables/asn.py

@@ -30,8 +30,8 @@ class ASNRangeTable(TenancyColumnsMixin, OrganizationalModelTable):
     class Meta(OrganizationalModelTable.Meta):
         model = ASNRange
         fields = (
-            'pk', 'name', 'slug', 'rir', 'start', 'end', 'asn_count', 'tenant', 'tenant_group', 'description', 'tags',
-            'created', 'last_updated', 'actions',
+            'pk', 'name', 'slug', 'rir', 'start', 'end', 'asn_count', 'tenant', 'tenant_group', 'description',
+            'comments', 'tags', 'created', 'last_updated', 'actions',
         )
         default_columns = ('pk', 'name', 'rir', 'start', 'end', 'tenant', 'asn_count', 'description')
 

+ 3 - 3
netbox/ipam/tables/ip.py

@@ -48,7 +48,7 @@ class RIRTable(OrganizationalModelTable):
     class Meta(OrganizationalModelTable.Meta):
         model = RIR
         fields = (
-            'pk', 'id', 'name', 'slug', 'is_private', 'aggregate_count', 'description', 'tags', 'created',
+            'pk', 'id', 'name', 'slug', 'is_private', 'aggregate_count', 'description', 'comments', 'tags', 'created',
             'last_updated', 'actions',
         )
         default_columns = ('pk', 'name', 'is_private', 'aggregate_count', 'description')
@@ -126,8 +126,8 @@ class RoleTable(OrganizationalModelTable):
     class Meta(OrganizationalModelTable.Meta):
         model = Role
         fields = (
-            'pk', 'id', 'name', 'slug', 'prefix_count', 'iprange_count', 'vlan_count', 'description', 'weight', 'tags',
-            'created', 'last_updated', 'actions',
+            'pk', 'id', 'name', 'slug', 'prefix_count', 'iprange_count', 'vlan_count', 'description', 'weight',
+            'comments', 'tags', 'created', 'last_updated', 'actions',
         )
         default_columns = ('pk', 'name', 'prefix_count', 'iprange_count', 'vlan_count', 'description')
 

+ 1 - 1
netbox/ipam/tables/vlans.py

@@ -66,7 +66,7 @@ class VLANGroupTable(TenancyColumnsMixin, OrganizationalModelTable):
         model = VLANGroup
         fields = (
             'pk', 'id', 'name', 'scope_type', 'scope', 'vid_ranges_list', 'vlan_count', 'slug', 'description',
-            'tenant', 'tenant_group', 'tags', 'created', 'last_updated', 'actions', 'utilization',
+            'tenant', 'tenant_group', 'comments', 'tags', 'created', 'last_updated', 'actions', 'utilization',
         )
         default_columns = (
             'pk', 'name', 'scope_type', 'scope', 'vlan_count', 'utilization', 'tenant', 'description'

+ 1 - 0
netbox/netbox/forms/bulk_edit.py

@@ -91,6 +91,7 @@ class OrganizationalModelBulkEditForm(OwnerMixin, NetBoxModelBulkEditForm):
         max_length=200,
         required=False
     )
+    comments = CommentField()
 
 
 class NestedGroupModelBulkEditForm(OwnerMixin, NetBoxModelBulkEditForm):

+ 1 - 0
netbox/netbox/forms/model_forms.py

@@ -91,6 +91,7 @@ class OrganizationalModelForm(OwnerMixin, NetBoxModelForm):
     Form for models which inherit from OrganizationalModel.
     """
     slug = SlugField()
+    comments = CommentField()
 
 
 class NestedGroupModelForm(OwnerMixin, NetBoxModelForm):

+ 1 - 0
netbox/netbox/graphql/filters.py

@@ -53,6 +53,7 @@ class OrganizationalModelFilter(NetBoxModelFilter):
     name: FilterLookup[str] | None = strawberry_django.filter_field()
     slug: FilterLookup[str] | None = strawberry_django.filter_field()
     description: FilterLookup[str] | None = strawberry_django.filter_field()
+    comments: FilterLookup[str] | None = strawberry_django.filter_field()
 
 
 @dataclass

+ 4 - 0
netbox/netbox/models/__init__.py

@@ -215,6 +215,10 @@ class OrganizationalModel(OwnerMixin, NetBoxModel):
         max_length=200,
         blank=True
     )
+    comments = models.TextField(
+        verbose_name=_('comments'),
+        blank=True
+    )
 
     class Meta:
         abstract = True

+ 3 - 0
netbox/netbox/tables/tables.py

@@ -285,6 +285,9 @@ class OrganizationalModelTable(NetBoxTable):
         linkify=True,
         verbose_name=_('Owner')
     )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
 
 
 class NestedGroupModelTable(NetBoxTable):

+ 1 - 0
netbox/templates/circuits/circuittype.html

@@ -43,6 +43,7 @@
   </div>
 	<div class="col col-12 col-md-6">
     {% include 'inc/panels/related_objects.html' %}
+    {% include 'inc/panels/comments.html' %}
     {% include 'inc/panels/custom_fields.html' %}
     {% plugin_right_page object %}
 	</div>

+ 1 - 0
netbox/templates/circuits/virtualcircuittype.html

@@ -43,6 +43,7 @@
   </div>
 	<div class="col col-12 col-md-6">
     {% include 'inc/panels/related_objects.html' %}
+    {% include 'inc/panels/comments.html' %}
     {% include 'inc/panels/custom_fields.html' %}
     {% plugin_right_page object %}
 	</div>

+ 1 - 0
netbox/templates/dcim/inventoryitemrole.html

@@ -40,6 +40,7 @@
     {% plugin_left_page object %}
 	</div>
 	<div class="col col-12 col-md-6">
+    {% include 'inc/panels/comments.html' %}
     {% include 'inc/panels/custom_fields.html' %}
     {% plugin_right_page object %}
   </div>

+ 1 - 0
netbox/templates/ipam/asnrange.html

@@ -44,6 +44,7 @@
       {% include 'inc/panels/tags.html' %}
     </div>
     <div class="col col-12 col-md-6">
+      {% include 'inc/panels/comments.html' %}
       {% include 'inc/panels/custom_fields.html' %}
       {% plugin_right_page object %}
     </div>

+ 1 - 0
netbox/templates/ipam/rir.html

@@ -37,6 +37,7 @@
 	</div>
 	<div class="col col-12 col-md-6">
     {% include 'inc/panels/related_objects.html' %}
+    {% include 'inc/panels/comments.html' %}
     {% include 'inc/panels/custom_fields.html' %}
     {% plugin_right_page object %}
   </div>

+ 1 - 0
netbox/templates/ipam/role.html

@@ -37,6 +37,7 @@
 	</div>
 	<div class="col col-12 col-md-6">
     {% include 'inc/panels/related_objects.html' %}
+    {% include 'inc/panels/comments.html' %}
     {% include 'inc/panels/custom_fields.html' %}
     {% plugin_right_page object %}
   </div>

+ 1 - 0
netbox/templates/ipam/vlangroup.html

@@ -62,6 +62,7 @@
 	</div>
 	<div class="col col-12 col-md-6">
     {% include 'inc/panels/related_objects.html' %}
+    {% include 'inc/panels/comments.html' %}
     {% include 'inc/panels/custom_fields.html' %}
     {% plugin_right_page object %}
   </div>

+ 1 - 0
netbox/templates/tenancy/contactrole.html

@@ -29,6 +29,7 @@
     </div>
     <div class="col col-12 col-md-6">
       {% include 'inc/panels/related_objects.html' %}
+      {% include 'inc/panels/comments.html' %}
       {% include 'inc/panels/custom_fields.html' %}
       {% plugin_right_page object %}
     </div>

+ 1 - 0
netbox/templates/virtualization/clustergroup.html

@@ -33,6 +33,7 @@
 	</div>
 	<div class="col col-12 col-md-6">
     {% include 'inc/panels/related_objects.html' %}
+    {% include 'inc/panels/comments.html' %}
     {% include 'inc/panels/custom_fields.html' %}
     {% plugin_right_page object %}
   </div>

+ 1 - 0
netbox/templates/virtualization/clustertype.html

@@ -39,6 +39,7 @@
 	</div>
 	<div class="col col-12 col-md-6">
     {% include 'inc/panels/related_objects.html' %}
+    {% include 'inc/panels/comments.html' %}
     {% include 'inc/panels/custom_fields.html' %}
     {% plugin_right_page object %}
   </div>

+ 1 - 0
netbox/templates/vpn/tunnelgroup.html

@@ -37,6 +37,7 @@
     </div>
     <div class="col col-12 col-md-6">
       {% include 'inc/panels/related_objects.html' %}
+      {% include 'inc/panels/comments.html' %}
       {% include 'inc/panels/custom_fields.html' %}
       {% plugin_right_page object %}
     </div>

+ 2 - 2
netbox/tenancy/api/serializers_/contacts.py

@@ -36,8 +36,8 @@ class ContactRoleSerializer(OrganizationalModelSerializer):
     class Meta:
         model = ContactRole
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'tags', 'custom_fields',
-            'created', 'last_updated',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'comments', 'tags',
+            'custom_fields', 'created', 'last_updated',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description')
 

+ 1 - 1
netbox/tenancy/forms/bulk_edit.py

@@ -72,7 +72,7 @@ class ContactRoleBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('description'),
     )
-    nullable_fields = ('description',)
+    nullable_fields = ('description', 'comments')
 
 
 class ContactBulkEditForm(PrimaryModelBulkEditForm):

+ 1 - 1
netbox/tenancy/forms/bulk_import.py

@@ -74,7 +74,7 @@ class ContactRoleImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = ContactRole
-        fields = ('name', 'slug', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'description', 'owner', 'comments', 'tags')
 
 
 class ContactImportForm(PrimaryModelImportForm):

+ 1 - 1
netbox/tenancy/forms/model_forms.py

@@ -84,7 +84,7 @@ class ContactRoleForm(OrganizationalModelForm):
 
     class Meta:
         model = ContactRole
-        fields = ('name', 'slug', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'description', 'owner', 'comments', 'tags')
 
 
 class ContactForm(PrimaryModelForm):

+ 18 - 0
netbox/tenancy/migrations/0022_add_comments_to_organizationalmodel.py

@@ -0,0 +1,18 @@
+# Generated by Django 5.2.8 on 2025-12-08 17:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('tenancy', '0021_owner'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='contactrole',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+    ]

+ 1 - 0
netbox/tenancy/search.py

@@ -37,6 +37,7 @@ class ContactRoleIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)
 

+ 1 - 1
netbox/tenancy/tables/contacts.py

@@ -44,7 +44,7 @@ class ContactRoleTable(OrganizationalModelTable):
 
     class Meta(OrganizationalModelTable.Meta):
         model = ContactRole
-        fields = ('pk', 'name', 'description', 'slug', 'tags', 'created', 'last_updated', 'actions')
+        fields = ('pk', 'name', 'description', 'comments', 'slug', 'tags', 'created', 'last_updated', 'actions')
         default_columns = ('pk', 'name', 'description')
 
 

+ 4 - 4
netbox/virtualization/api/serializers_/clusters.py

@@ -23,8 +23,8 @@ class ClusterTypeSerializer(OrganizationalModelSerializer):
     class Meta:
         model = ClusterType
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'tags', 'custom_fields',
-            'created', 'last_updated', 'cluster_count',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'comments', 'tags',
+            'custom_fields', 'created', 'last_updated', 'cluster_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'cluster_count')
 
@@ -37,8 +37,8 @@ class ClusterGroupSerializer(OrganizationalModelSerializer):
     class Meta:
         model = ClusterGroup
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'tags', 'custom_fields',
-            'created', 'last_updated', 'cluster_count',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'comments', 'tags',
+            'custom_fields', 'created', 'last_updated', 'cluster_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'cluster_count')
 

+ 2 - 2
netbox/virtualization/forms/bulk_edit.py

@@ -34,7 +34,7 @@ class ClusterTypeBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('description'),
     )
-    nullable_fields = ('description',)
+    nullable_fields = ('description', 'comments')
 
 
 class ClusterGroupBulkEditForm(OrganizationalModelBulkEditForm):
@@ -42,7 +42,7 @@ class ClusterGroupBulkEditForm(OrganizationalModelBulkEditForm):
     fieldsets = (
         FieldSet('description'),
     )
-    nullable_fields = ('description',)
+    nullable_fields = ('description', 'comments')
 
 
 class ClusterBulkEditForm(ScopedBulkEditForm, PrimaryModelBulkEditForm):

+ 2 - 2
netbox/virtualization/forms/bulk_import.py

@@ -28,14 +28,14 @@ class ClusterTypeImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = ClusterType
-        fields = ('name', 'slug', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'description', 'owner', 'comments', 'tags')
 
 
 class ClusterGroupImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = ClusterGroup
-        fields = ('name', 'slug', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'description', 'owner', 'comments', 'tags')
 
 
 class ClusterImportForm(ScopedImportForm, PrimaryModelImportForm):

+ 2 - 2
netbox/virtualization/forms/model_forms.py

@@ -39,7 +39,7 @@ class ClusterTypeForm(OrganizationalModelForm):
     class Meta:
         model = ClusterType
         fields = (
-            'name', 'slug', 'description', 'owner', 'tags',
+            'name', 'slug', 'description', 'owner', 'comments', 'tags',
         )
 
 
@@ -51,7 +51,7 @@ class ClusterGroupForm(OrganizationalModelForm):
     class Meta:
         model = ClusterGroup
         fields = (
-            'name', 'slug', 'description', 'owner', 'tags',
+            'name', 'slug', 'description', 'owner', 'comments', 'tags',
         )
 
 

+ 23 - 0
netbox/virtualization/migrations/0051_add_comments_to_organizationalmodel.py

@@ -0,0 +1,23 @@
+# Generated by Django 5.2.8 on 2025-12-08 17:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('virtualization', '0050_virtualmachine_start_on_boot'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='clustergroup',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AddField(
+            model_name='clustertype',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+    ]

+ 2 - 0
netbox/virtualization/search.py

@@ -20,6 +20,7 @@ class ClusterGroupIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)
 
@@ -31,6 +32,7 @@ class ClusterTypeIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)
 

+ 4 - 3
netbox/virtualization/tables/clusters.py

@@ -29,7 +29,8 @@ class ClusterTypeTable(OrganizationalModelTable):
     class Meta(OrganizationalModelTable.Meta):
         model = ClusterType
         fields = (
-            'pk', 'id', 'name', 'slug', 'cluster_count', 'description', 'created', 'last_updated', 'tags', 'actions',
+            'pk', 'id', 'name', 'slug', 'cluster_count', 'description', 'comments', 'created', 'last_updated', 'tags',
+            'actions',
         )
         default_columns = ('pk', 'name', 'cluster_count', 'description')
 
@@ -51,8 +52,8 @@ class ClusterGroupTable(ContactsColumnMixin, OrganizationalModelTable):
     class Meta(OrganizationalModelTable.Meta):
         model = ClusterGroup
         fields = (
-            'pk', 'id', 'name', 'slug', 'cluster_count', 'description', 'contacts', 'tags', 'created', 'last_updated',
-            'actions',
+            'pk', 'id', 'name', 'slug', 'cluster_count', 'description', 'comments', 'contacts', 'tags', 'created',
+            'last_updated', 'actions',
         )
         default_columns = ('pk', 'name', 'cluster_count', 'description')
 

+ 2 - 2
netbox/vpn/api/serializers_/tunnels.py

@@ -28,8 +28,8 @@ class TunnelGroupSerializer(OrganizationalModelSerializer):
     class Meta:
         model = TunnelGroup
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'tags', 'custom_fields',
-            'created', 'last_updated', 'tunnel_count',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'comments', 'tags',
+            'custom_fields', 'created', 'last_updated', 'tunnel_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'tunnel_count')
 

+ 1 - 1
netbox/vpn/forms/bulk_edit.py

@@ -25,7 +25,7 @@ __all__ = (
 
 class TunnelGroupBulkEditForm(OrganizationalModelBulkEditForm):
     model = TunnelGroup
-    nullable_fields = ('description',)
+    nullable_fields = ('description', 'comments')
 
 
 class TunnelBulkEditForm(PrimaryModelBulkEditForm):

+ 1 - 1
netbox/vpn/forms/bulk_import.py

@@ -28,7 +28,7 @@ class TunnelGroupImportForm(OrganizationalModelImportForm):
 
     class Meta:
         model = TunnelGroup
-        fields = ('name', 'slug', 'description', 'owner', 'tags')
+        fields = ('name', 'slug', 'description', 'owner', 'comments', 'tags')
 
 
 class TunnelImportForm(PrimaryModelImportForm):

+ 1 - 1
netbox/vpn/forms/model_forms.py

@@ -37,7 +37,7 @@ class TunnelGroupForm(OrganizationalModelForm):
     class Meta:
         model = TunnelGroup
         fields = [
-            'name', 'slug', 'description', 'owner', 'tags',
+            'name', 'slug', 'description', 'owner', 'comments', 'tags',
         ]
 
 

+ 18 - 0
netbox/vpn/migrations/0011_add_comments_to_organizationalmodel.py

@@ -0,0 +1,18 @@
+# Generated by Django 5.2.8 on 2025-12-08 17:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('vpn', '0010_owner'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='tunnelgroup',
+            name='comments',
+            field=models.TextField(blank=True),
+        ),
+    ]

+ 1 - 0
netbox/vpn/search.py

@@ -21,6 +21,7 @@ class TunnelGroupIndex(SearchIndex):
         ('name', 100),
         ('slug', 110),
         ('description', 500),
+        ('comments', 5000),
     )
     display_attrs = ('description',)
 

+ 2 - 2
netbox/vpn/tables/tunnels.py

@@ -30,8 +30,8 @@ class TunnelGroupTable(ContactsColumnMixin, OrganizationalModelTable):
     class Meta(OrganizationalModelTable.Meta):
         model = TunnelGroup
         fields = (
-            'pk', 'id', 'name', 'tunnel_count', 'description', 'slug', 'contacts', 'tags', 'actions', 'created',
-            'last_updated',
+            'pk', 'id', 'name', 'tunnel_count', 'description', 'comments', 'slug', 'contacts', 'tags', 'actions',
+            'created', 'last_updated',
         )
         default_columns = ('pk', 'name', 'tunnel_count', 'description')