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 %}