diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index b4096973a..a1d1102de 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -797,41 +797,49 @@ class DeviceTypeView(generic.ObjectView): class DeviceTypeConsolePortsView(DeviceTypeComponentsView): child_model = ConsolePortTemplate table = tables.ConsolePortTemplateTable + filterset = filtersets.ConsolePortTemplateFilterSet class DeviceTypeConsoleServerPortsView(DeviceTypeComponentsView): child_model = ConsoleServerPortTemplate table = tables.ConsoleServerPortTemplateTable + filterset = filtersets.ConsoleServerPortTemplateFilterSet class DeviceTypePowerPortsView(DeviceTypeComponentsView): child_model = PowerPortTemplate table = tables.PowerPortTemplateTable + filterset = filtersets.PowerPortTemplateFilterSet class DeviceTypePowerOutletsView(DeviceTypeComponentsView): child_model = PowerOutletTemplate table = tables.PowerOutletTemplateTable + filterset = filtersets.PowerOutletTemplateFilterSet class DeviceTypeInterfacesView(DeviceTypeComponentsView): child_model = InterfaceTemplate table = tables.InterfaceTemplateTable + filterset = filtersets.InterfaceTemplateFilterSet class DeviceTypeFrontPortsView(DeviceTypeComponentsView): child_model = FrontPortTemplate table = tables.FrontPortTemplateTable + filterset = filtersets.FrontPortTemplateFilterSet class DeviceTypeRearPortsView(DeviceTypeComponentsView): child_model = RearPortTemplate table = tables.RearPortTemplateTable + filterset = filtersets.RearPortTemplateFilterSet class DeviceTypeDeviceBaysView(DeviceTypeComponentsView): child_model = DeviceBayTemplate table = tables.DeviceBayTemplateTable + filterset = filtersets.DeviceBayTemplateFilterSet class DeviceTypeEditView(generic.ObjectEditView): @@ -1328,30 +1336,35 @@ class DeviceView(generic.ObjectView): class DeviceConsolePortsView(DeviceComponentsView): child_model = ConsolePort table = tables.DeviceConsolePortTable + filterset = filtersets.ConsolePortFilterSet template_name = 'dcim/device/consoleports.html' class DeviceConsoleServerPortsView(DeviceComponentsView): child_model = ConsoleServerPort table = tables.DeviceConsoleServerPortTable + filterset = filtersets.ConsoleServerPortFilterSet template_name = 'dcim/device/consoleserverports.html' class DevicePowerPortsView(DeviceComponentsView): child_model = PowerPort table = tables.DevicePowerPortTable + filterset = filtersets.PowerPortFilterSet template_name = 'dcim/device/powerports.html' class DevicePowerOutletsView(DeviceComponentsView): child_model = PowerOutlet table = tables.DevicePowerOutletTable + filterset = filtersets.PowerOutletFilterSet template_name = 'dcim/device/poweroutlets.html' class DeviceInterfacesView(DeviceComponentsView): child_model = Interface table = tables.DeviceInterfaceTable + filterset = filtersets.InterfaceFilterSet template_name = 'dcim/device/interfaces.html' def get_children(self, request, parent): @@ -1364,24 +1377,28 @@ class DeviceInterfacesView(DeviceComponentsView): class DeviceFrontPortsView(DeviceComponentsView): child_model = FrontPort table = tables.DeviceFrontPortTable + filterset = filtersets.FrontPortFilterSet template_name = 'dcim/device/frontports.html' class DeviceRearPortsView(DeviceComponentsView): child_model = RearPort table = tables.DeviceRearPortTable + filterset = filtersets.RearPortFilterSet template_name = 'dcim/device/rearports.html' class DeviceDeviceBaysView(DeviceComponentsView): child_model = DeviceBay table = tables.DeviceDeviceBayTable + filterset = filtersets.DeviceBayFilterSet template_name = 'dcim/device/devicebays.html' class DeviceInventoryView(DeviceComponentsView): child_model = InventoryItem table = tables.DeviceInventoryItemTable + filterset = filtersets.InventoryItemFilterSet template_name = 'dcim/device/inventory.html' diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 08253c054..7e6e1725f 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -1,21 +1,22 @@ from django.contrib.contenttypes.models import ContentType from django.db.models import Prefetch from django.db.models.expressions import RawSQL -from django.http import Http404 from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse +from dcim.filtersets import InterfaceFilterSet from dcim.models import Device, Interface, Site from dcim.tables import SiteTable from netbox.views import generic from utilities.tables import paginate_table from utilities.utils import count_related +from virtualization.filtersets import VMInterfaceFilterSet from virtualization.models import VirtualMachine, VMInterface from . import filtersets, forms, tables from .constants import * from .models import * from .models import ASN -from .utils import add_available_ipaddresses, add_requested_prefixes, add_available_vlans +from .utils import add_requested_prefixes, add_available_vlans # @@ -457,6 +458,7 @@ class PrefixPrefixesView(generic.ObjectChildrenView): queryset = Prefix.objects.all() child_model = Prefix table = tables.PrefixTable + filterset = filtersets.PrefixFilterSet template_name = 'ipam/prefix/prefixes.html' def get_children(self, request, parent): @@ -483,6 +485,7 @@ class PrefixIPRangesView(generic.ObjectChildrenView): queryset = Prefix.objects.all() child_model = IPRange table = tables.IPRangeTable + filterset = filtersets.IPRangeFilterSet template_name = 'ipam/prefix/ip_ranges.html' def get_children(self, request, parent): @@ -499,6 +502,7 @@ class PrefixIPAddressesView(generic.ObjectChildrenView): queryset = Prefix.objects.all() child_model = IPAddress table = tables.IPAddressTable + filterset = filtersets.IPAddressFilterSet template_name = 'ipam/prefix/ip_addresses.html' def get_children(self, request, parent): @@ -560,6 +564,7 @@ class IPRangeIPAddressesView(generic.ObjectChildrenView): queryset = IPRange.objects.all() child_model = IPAddress table = tables.IPAddressTable + filterset = filtersets.IPAddressFilterSet template_name = 'ipam/iprange/ip_addresses.html' def get_children(self, request, parent): @@ -959,6 +964,7 @@ class VLANInterfacesView(generic.ObjectChildrenView): queryset = VLAN.objects.all() child_model = Interface table = tables.VLANDevicesTable + filterset = InterfaceFilterSet template_name = 'ipam/vlan/interfaces.html' def get_children(self, request, parent): @@ -974,6 +980,7 @@ class VLANVMInterfacesView(generic.ObjectChildrenView): queryset = VLAN.objects.all() child_model = VMInterface table = tables.VLANVirtualMachinesTable + filterset = VMInterfaceFilterSet template_name = 'ipam/vlan/vminterfaces.html' def get_children(self, request, parent): diff --git a/netbox/netbox/views/generic.py b/netbox/netbox/views/generic.py index 62d580bf5..84928dfff 100644 --- a/netbox/netbox/views/generic.py +++ b/netbox/netbox/views/generic.py @@ -84,11 +84,12 @@ class ObjectChildrenView(ObjectView): queryset = None child_model = None table = None + filterset = None template_name = None def get_children(self, request, parent): """ - Return a QuerySet or iterable of child objects. + Return a QuerySet of child objects. request: The current request parent: The parent object @@ -102,6 +103,9 @@ class ObjectChildrenView(ObjectView): instance = get_object_or_404(self.queryset, **kwargs) child_objects = self.get_children(request, instance) + if self.filterset: + child_objects = self.filterset(request.GET, child_objects).qs + permissions = {} for action in ('change', 'delete'): perm_name = get_permission_for_model(self.child_model, action) @@ -113,6 +117,13 @@ class ObjectChildrenView(ObjectView): table.columns.show('pk') paginate_table(table, request) + # If this is an HTMX request, return only the rendered table HTML + if is_htmx(request): + return render(request, 'htmx/table.html', { + 'object': instance, + 'table': table, + }) + return render(request, self.get_template_name(), { 'object': instance, 'table': table, diff --git a/netbox/templates/dcim/device/consoleports.html b/netbox/templates/dcim/device/consoleports.html index 066c19b73..b5a8a0f39 100644 --- a/netbox/templates/dcim/device/consoleports.html +++ b/netbox/templates/dcim/device/consoleports.html @@ -6,10 +6,14 @@ {% block content %}
{% csrf_token %} - {% include 'inc/table_controls.html' with table_modal="DeviceConsolePortTable_config" %} -
- {% render_table table 'inc/table.html' %} + {% include 'inc/table_controls_htmx.html' with table_modal="DeviceConsolePortTable_config" %} + +
+
+ {% include 'htmx/table.html' %} +
+
{% if perms.dcim.change_consoleport %} @@ -38,6 +42,5 @@ {% endif %}
- {% include 'inc/paginator.html' with paginator=table.paginator page=table.page %} {% table_config_form table %} {% endblock %} diff --git a/netbox/templates/dcim/device/consoleserverports.html b/netbox/templates/dcim/device/consoleserverports.html index 97c98bb9f..f77ef0169 100644 --- a/netbox/templates/dcim/device/consoleserverports.html +++ b/netbox/templates/dcim/device/consoleserverports.html @@ -6,10 +6,14 @@ {% block content %}
{% csrf_token %} - {% include 'inc/table_controls.html' with table_modal="DeviceConsoleServerPortTable_config" %} -
- {% render_table table 'inc/table.html' %} + {% include 'inc/table_controls_htmx.html' with table_modal="DeviceConsoleServerPortTable_config" %} + +
+
+ {% include 'htmx/table.html' %} +
+
{% if perms.dcim.change_consoleserverport %} diff --git a/netbox/templates/dcim/device/devicebays.html b/netbox/templates/dcim/device/devicebays.html index 572e8d110..960610fa8 100644 --- a/netbox/templates/dcim/device/devicebays.html +++ b/netbox/templates/dcim/device/devicebays.html @@ -6,10 +6,14 @@ {% block content %} {% csrf_token %} - {% include 'inc/table_controls.html' with table_modal="DeviceDeviceBayTable_config" %} -
- {% render_table table 'inc/table.html' %} + {% include 'inc/table_controls_htmx.html' with table_modal="DeviceDeviceBayTable_config" %} + +
+
+ {% include 'htmx/table.html' %} +
+
{% if perms.dcim.change_devicebay %} diff --git a/netbox/templates/dcim/device/frontports.html b/netbox/templates/dcim/device/frontports.html index 83dd2dc65..18c08abe4 100644 --- a/netbox/templates/dcim/device/frontports.html +++ b/netbox/templates/dcim/device/frontports.html @@ -6,10 +6,14 @@ {% block content %} {% csrf_token %} - {% include 'inc/table_controls.html' with table_modal="DeviceFrontPortTable_config" %} -
- {% render_table table 'inc/table.html' %} + {% include 'inc/table_controls_htmx.html' with table_modal="DeviceFrontPortTable_config" %} + +
+
+ {% include 'htmx/table.html' %} +
+
{% if perms.dcim.change_frontport %} diff --git a/netbox/templates/dcim/device/interfaces.html b/netbox/templates/dcim/device/interfaces.html index 7d9926fce..c7d86ae89 100644 --- a/netbox/templates/dcim/device/interfaces.html +++ b/netbox/templates/dcim/device/interfaces.html @@ -9,7 +9,15 @@
- +
@@ -34,9 +42,13 @@
-
- {% render_table table 'inc/table.html' %} + +
+
+ {% include 'htmx/table.html' %} +
+
{% if perms.dcim.change_interface %} diff --git a/netbox/templates/dcim/device/inventory.html b/netbox/templates/dcim/device/inventory.html index ee1ce9f52..699ae378f 100644 --- a/netbox/templates/dcim/device/inventory.html +++ b/netbox/templates/dcim/device/inventory.html @@ -6,10 +6,14 @@ {% block content %} {% csrf_token %} - {% include 'inc/table_controls.html' with table_modal="DeviceInventoryItemTable_config" %} -
- {% render_table table 'inc/table.html' %} + {% include 'inc/table_controls_htmx.html' with table_modal="DeviceInventoryItemTable_config" %} + +
+
+ {% include 'htmx/table.html' %} +
+
{% if perms.dcim.change_inventoryitem %} diff --git a/netbox/templates/dcim/device/poweroutlets.html b/netbox/templates/dcim/device/poweroutlets.html index ed49d24b8..af94e1264 100644 --- a/netbox/templates/dcim/device/poweroutlets.html +++ b/netbox/templates/dcim/device/poweroutlets.html @@ -6,10 +6,14 @@ {% block content %} {% csrf_token %} - {% include 'inc/table_controls.html' with table_modal="DevicePowerOutletTable_config" %} -
- {% render_table table 'inc/table.html' %} + {% include 'inc/table_controls_htmx.html' with table_modal="DevicePowerOutletTable_config" %} + +
+
+ {% include 'htmx/table.html' %} +
+
{% if perms.dcim.change_powerport %} diff --git a/netbox/templates/dcim/device/powerports.html b/netbox/templates/dcim/device/powerports.html index 453c5f5b0..7b993bc73 100644 --- a/netbox/templates/dcim/device/powerports.html +++ b/netbox/templates/dcim/device/powerports.html @@ -6,10 +6,14 @@ {% block content %} {% csrf_token %} - {% include 'inc/table_controls.html' with table_modal="DevicePowerPortTable_config" %} -
- {% render_table table 'inc/table.html' %} + {% include 'inc/table_controls_htmx.html' with table_modal="DevicePowerPortTable_config" %} + +
+
+ {% include 'htmx/table.html' %} +
+
{% if perms.dcim.change_powerport %} diff --git a/netbox/templates/dcim/device/rearports.html b/netbox/templates/dcim/device/rearports.html index 37807cd14..86f89e459 100644 --- a/netbox/templates/dcim/device/rearports.html +++ b/netbox/templates/dcim/device/rearports.html @@ -6,10 +6,14 @@ {% block content %} {% csrf_token %} - {% include 'inc/table_controls.html' with table_modal="DeviceRearPortTable_config" %} -
- {% render_table table 'inc/table.html' %} + {% include 'inc/table_controls_htmx.html' with table_modal="DeviceRearPortTable_config" %} + +
+
+ {% include 'htmx/table.html' %} +
+
{% if perms.dcim.change_rearport %} diff --git a/netbox/templates/dcim/devicetype/component_templates.html b/netbox/templates/dcim/devicetype/component_templates.html index d83a232cd..b1e0daf78 100644 --- a/netbox/templates/dcim/devicetype/component_templates.html +++ b/netbox/templates/dcim/devicetype/component_templates.html @@ -7,11 +7,9 @@ {% csrf_token %}
-
- {{ title }} -
-
- {% render_table table 'inc/table.html' %} +
{{ title }}
+
+ {% include 'htmx/table.html' %}