From 1a2dae3471c4c7102339175f352c4c94efec10f9 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 16 Jan 2023 15:50:45 -0500 Subject: [PATCH] Closes #8184: Enable HTMX for embedded tables (#11518) * Enable HTMX rendering for embedded tables * Start converting embedded tables to use HTMX (WIP) * Additional table conversions (WIP) * Standardize HTMX usage for nested group models * Enable HTMX for additional emebedded tables * Fix HTMX table rendering for ObjectChildrenView * Standardize usage of inc/panel_table.html * Hide selection boxes in embedded tables --- netbox/circuits/views.py | 38 ----- netbox/dcim/views.py | 145 ++---------------- netbox/ipam/views.py | 60 +------- netbox/netbox/tables/tables.py | 17 +- netbox/netbox/views/generic/bulk_views.py | 7 +- netbox/templates/circuits/circuittype.html | 10 +- netbox/templates/circuits/provider.html | 10 +- .../templates/circuits/providernetwork.html | 8 +- netbox/templates/dcim/connections_list.html | 2 +- .../templates/dcim/device/consoleports.html | 2 +- .../dcim/device/consoleserverports.html | 2 +- netbox/templates/dcim/device/devicebays.html | 2 +- netbox/templates/dcim/device/frontports.html | 2 +- netbox/templates/dcim/device/interfaces.html | 2 +- netbox/templates/dcim/device/inventory.html | 2 +- netbox/templates/dcim/device/modulebays.html | 2 +- .../templates/dcim/device/poweroutlets.html | 2 +- netbox/templates/dcim/device/powerports.html | 2 +- netbox/templates/dcim/device/rearports.html | 2 +- netbox/templates/dcim/devicerole.html | 4 +- .../dcim/devicetype/component_templates.html | 4 +- netbox/templates/dcim/interface.html | 11 +- netbox/templates/dcim/location.html | 10 +- netbox/templates/dcim/manufacturer.html | 14 +- .../dcim/moduletype/component_templates.html | 4 +- netbox/templates/dcim/platform.html | 10 +- netbox/templates/dcim/powerpanel.html | 70 +++++---- netbox/templates/dcim/rackrole.html | 10 +- netbox/templates/dcim/region.html | 25 ++- netbox/templates/dcim/sitegroup.html | 25 ++- .../templates/dcim/virtualdevicecontext.html | 14 +- netbox/templates/generic/object_list.html | 2 +- netbox/templates/home.html | 7 +- netbox/templates/htmx/table.html | 4 +- netbox/templates/inc/paginator_htmx.html | 24 +-- netbox/templates/inc/panel_table.html | 22 ++- netbox/templates/inc/table_htmx.html | 109 +++++++------ netbox/templates/ipam/aggregate/prefixes.html | 2 +- netbox/templates/ipam/asn.html | 16 +- netbox/templates/ipam/fhrpgroup.html | 22 +-- netbox/templates/ipam/ipaddress.html | 25 +-- .../templates/ipam/iprange/ip_addresses.html | 2 +- netbox/templates/ipam/l2vpn.html | 7 +- .../templates/ipam/prefix/ip_addresses.html | 2 +- netbox/templates/ipam/prefix/ip_ranges.html | 2 +- netbox/templates/ipam/prefix/prefixes.html | 2 +- netbox/templates/ipam/rir.html | 12 +- netbox/templates/ipam/role.html | 28 +--- netbox/templates/ipam/vlan.html | 32 ++-- netbox/templates/ipam/vlan/interfaces.html | 2 +- netbox/templates/ipam/vlan/vminterfaces.html | 2 +- netbox/templates/search.html | 2 +- netbox/templates/tenancy/contactgroup.html | 31 ++-- netbox/templates/tenancy/tenantgroup.html | 24 ++- .../virtualization/cluster/devices.html | 2 +- .../cluster/virtual_machines.html | 2 +- .../virtualization/clustergroup.html | 10 +- .../templates/virtualization/clustertype.html | 10 +- .../virtualmachine/interfaces.html | 2 +- .../templates/virtualization/vminterface.html | 15 +- .../templates/wireless/wirelesslangroup.html | 26 +++- netbox/tenancy/views.py | 37 ----- netbox/utilities/htmx.py | 14 ++ netbox/virtualization/views.py | 20 --- netbox/wireless/views.py | 11 -- 65 files changed, 381 insertions(+), 667 deletions(-) diff --git a/netbox/circuits/views.py b/netbox/circuits/views.py index 3168509ba3..021709be12 100644 --- a/netbox/circuits/views.py +++ b/netbox/circuits/views.py @@ -29,20 +29,6 @@ class ProviderListView(generic.ObjectListView): class ProviderView(generic.ObjectView): queryset = Provider.objects.all() - def get_extra_context(self, request, instance): - circuits = Circuit.objects.restrict(request.user, 'view').filter( - provider=instance - ).prefetch_related( - 'tenant__group', 'termination_a__site', 'termination_z__site', - 'termination_a__provider_network', 'termination_z__provider_network', - ) - circuits_table = tables.CircuitTable(circuits, user=request.user, exclude=('provider',)) - circuits_table.configure(request) - - return { - 'circuits_table': circuits_table, - } - @register_model_view(Provider, 'edit') class ProviderEditView(generic.ObjectEditView): @@ -93,21 +79,6 @@ class ProviderNetworkListView(generic.ObjectListView): class ProviderNetworkView(generic.ObjectView): queryset = ProviderNetwork.objects.all() - def get_extra_context(self, request, instance): - circuits = Circuit.objects.restrict(request.user, 'view').filter( - Q(termination_a__provider_network=instance.pk) | - Q(termination_z__provider_network=instance.pk) - ).prefetch_related( - 'tenant__group', 'termination_a__site', 'termination_z__site', - 'termination_a__provider_network', 'termination_z__provider_network', - ) - circuits_table = tables.CircuitTable(circuits, user=request.user) - circuits_table.configure(request) - - return { - 'circuits_table': circuits_table, - } - @register_model_view(ProviderNetwork, 'edit') class ProviderNetworkEditView(generic.ObjectEditView): @@ -156,15 +127,6 @@ class CircuitTypeListView(generic.ObjectListView): class CircuitTypeView(generic.ObjectView): queryset = CircuitType.objects.all() - def get_extra_context(self, request, instance): - circuits = Circuit.objects.restrict(request.user, 'view').filter(type=instance) - circuits_table = tables.CircuitTable(circuits, user=request.user, exclude=('type',)) - circuits_table.configure(request) - - return { - 'circuits_table': circuits_table, - } - @register_model_view(CircuitType, 'edit') class CircuitTypeEditView(generic.ObjectEditView): diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 9b49e799c8..63fdc47e08 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -14,7 +14,7 @@ from circuits.models import Circuit, CircuitTermination from extras.views import ObjectConfigContextView from ipam.models import ASN, IPAddress, Prefix, Service, VLAN, VLANGroup -from ipam.tables import AssignedIPAddressesTable, InterfaceVLANTable +from ipam.tables import InterfaceVLANTable from netbox.views import generic from utilities.forms import ConfirmationForm from utilities.paginator import EnhancedPaginator, get_paginate_count @@ -212,30 +212,6 @@ class RegionListView(generic.ObjectListView): class RegionView(generic.ObjectView): queryset = Region.objects.all() - def get_extra_context(self, request, instance): - child_regions = Region.objects.add_related_count( - Region.objects.all(), - Site, - 'region', - 'site_count', - cumulative=True - ).restrict(request.user, 'view').filter( - parent__in=instance.get_descendants(include_self=True) - ) - child_regions_table = tables.RegionTable(child_regions) - child_regions_table.columns.hide('actions') - - sites = Site.objects.restrict(request.user, 'view').filter( - region=instance - ) - sites_table = tables.SiteTable(sites, user=request.user, exclude=('region',)) - sites_table.configure(request) - - return { - 'child_regions_table': child_regions_table, - 'sites_table': sites_table, - } - @register_model_view(Region, 'edit') class RegionEditView(generic.ObjectEditView): @@ -300,30 +276,6 @@ class SiteGroupListView(generic.ObjectListView): class SiteGroupView(generic.ObjectView): queryset = SiteGroup.objects.all() - def get_extra_context(self, request, instance): - child_groups = SiteGroup.objects.add_related_count( - SiteGroup.objects.all(), - Site, - 'group', - 'site_count', - cumulative=True - ).restrict(request.user, 'view').filter( - parent__in=instance.get_descendants(include_self=True) - ) - child_groups_table = tables.SiteGroupTable(child_groups) - child_groups_table.columns.hide('actions') - - sites = Site.objects.restrict(request.user, 'view').filter( - group=instance - ) - sites_table = tables.SiteTable(sites, user=request.user, exclude=('group',)) - sites_table.configure(request) - - return { - 'child_groups_table': child_groups_table, - 'sites_table': sites_table, - } - @register_model_view(SiteGroup, 'edit') class SiteGroupEditView(generic.ObjectEditView): @@ -493,22 +445,6 @@ def get_extra_context(self, request, instance): rack_count = Rack.objects.filter(location__in=location_ids).count() device_count = Device.objects.filter(location__in=location_ids).count() - child_locations = Location.objects.add_related_count( - Location.objects.add_related_count( - Location.objects.all(), - Device, - 'location', - 'device_count', - cumulative=True - ), - Rack, - 'location', - 'rack_count', - cumulative=True - ).filter(pk__in=location_ids).exclude(pk=instance.pk) - child_locations_table = tables.LocationTable(child_locations, user=request.user) - child_locations_table.configure(request) - nonracked_devices = Device.objects.filter( location=instance, rack__isnull=True, @@ -518,7 +454,6 @@ def get_extra_context(self, request, instance): return { 'rack_count': rack_count, 'device_count': device_count, - 'child_locations_table': child_locations_table, 'nonracked_devices': nonracked_devices.order_by('-pk')[:10], 'total_nonracked_devices_count': nonracked_devices.count(), } @@ -583,20 +518,6 @@ class RackRoleListView(generic.ObjectListView): class RackRoleView(generic.ObjectView): queryset = RackRole.objects.all() - def get_extra_context(self, request, instance): - racks = Rack.objects.restrict(request.user, 'view').filter(role=instance).annotate( - device_count=count_related(Device, 'rack') - ) - - racks_table = tables.RackTable(racks, user=request.user, exclude=( - 'role', 'get_utilization', 'get_power_utilization', - )) - racks_table.configure(request) - - return { - 'racks_table': racks_table, - } - @register_model_view(RackRole, 'edit') class RackRoleEditView(generic.ObjectEditView): @@ -859,8 +780,6 @@ class ManufacturerView(generic.ObjectView): def get_extra_context(self, request, instance): device_types = DeviceType.objects.restrict(request.user, 'view').filter( manufacturer=instance - ).annotate( - instance_count=count_related(Device, 'device_type') ) module_types = ModuleType.objects.restrict(request.user, 'view').filter( manufacturer=instance @@ -869,13 +788,10 @@ def get_extra_context(self, request, instance): manufacturer=instance ) - devicetypes_table = tables.DeviceTypeTable(device_types, user=request.user, exclude=('manufacturer',)) - devicetypes_table.configure(request) - return { - 'devicetypes_table': devicetypes_table, - 'inventory_item_count': inventory_items.count(), - 'module_type_count': module_types.count(), + 'devicetype_count': device_types.count(), + 'inventoryitem_count': inventory_items.count(), + 'moduletype_count': module_types.count(), } @@ -1726,19 +1642,6 @@ class DeviceRoleListView(generic.ObjectListView): class DeviceRoleView(generic.ObjectView): queryset = DeviceRole.objects.all() - def get_extra_context(self, request, instance): - devices = Device.objects.restrict(request.user, 'view').filter( - device_role=instance - ) - devices_table = tables.DeviceTable(devices, user=request.user, exclude=('device_role',)) - devices_table.configure(request) - - return { - 'devices_table': devices_table, - 'device_count': Device.objects.filter(device_role=instance).count(), - 'virtualmachine_count': VirtualMachine.objects.filter(role=instance).count(), - } - @register_model_view(DeviceRole, 'devices', path='devices') class DeviceRoleDevicesView(generic.ObjectChildrenView): @@ -1833,12 +1736,13 @@ def get_extra_context(self, request, instance): devices = Device.objects.restrict(request.user, 'view').filter( platform=instance ) - devices_table = tables.DeviceTable(devices, user=request.user, exclude=('platform',)) - devices_table.configure(request) + virtual_machines = VirtualMachine.objects.restrict(request.user, 'view').filter( + platform=instance + ) return { - 'devices_table': devices_table, - 'virtualmachine_count': VirtualMachine.objects.filter(platform=instance).count() + 'device_count': devices.count(), + 'virtualmachine_count': virtual_machines.count() } @@ -2520,12 +2424,6 @@ def get_extra_context(self, request, instance): orderable=False ) - # Get assigned IP addresses - ipaddress_table = AssignedIPAddressesTable( - data=instance.ip_addresses.restrict(request.user, 'view').prefetch_related('vrf', 'tenant'), - orderable=False - ) - # Get bridge interfaces bridge_interfaces = Interface.objects.restrict(request.user, 'view').filter(bridge=instance) bridge_interfaces_tables = tables.InterfaceTable( @@ -2558,7 +2456,6 @@ def get_extra_context(self, request, instance): return { 'vdc_table': vdc_table, - 'ipaddress_table': ipaddress_table, 'bridge_interfaces_table': bridge_interfaces_tables, 'child_interfaces_table': child_interfaces_tables, 'vlan_table': vlan_table, @@ -3533,20 +3430,6 @@ class PowerPanelListView(generic.ObjectListView): class PowerPanelView(generic.ObjectView): queryset = PowerPanel.objects.all() - def get_extra_context(self, request, instance): - power_feeds = PowerFeed.objects.restrict(request.user).filter(power_panel=instance) - powerfeed_table = tables.PowerFeedTable( - data=power_feeds, - orderable=False - ) - if request.user.has_perm('dcim.delete_cable'): - powerfeed_table.columns.show('pk') - powerfeed_table.exclude = ['power_panel'] - - return { - 'powerfeed_table': powerfeed_table, - } - @register_model_view(PowerPanel, 'edit') class PowerPanelEditView(generic.ObjectEditView): @@ -3648,16 +3531,6 @@ class VirtualDeviceContextListView(generic.ObjectListView): class VirtualDeviceContextView(generic.ObjectView): queryset = VirtualDeviceContext.objects.all() - def get_extra_context(self, request, instance): - interfaces_table = tables.InterfaceTable(instance.interfaces, user=request.user) - interfaces_table.configure(request) - interfaces_table.columns.hide('device') - - return { - 'interfaces_table': interfaces_table, - 'interface_count': instance.interfaces.count(), - } - @register_model_view(VirtualDeviceContext, 'edit') class VirtualDeviceContextEditView(generic.ObjectEditView): diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 130014f3f1..9741be66b2 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -5,11 +5,9 @@ from django.urls import reverse from django.utils.translation import gettext as _ -from circuits.models import Provider, Circuit -from circuits.tables import ProviderTable +from circuits.models import Provider from dcim.filtersets import InterfaceFilterSet from dcim.models import Interface, Site, Device -from dcim.tables import SiteTable from netbox.views import generic from utilities.utils import count_related from utilities.views import ViewTab, register_model_view @@ -167,17 +165,6 @@ class RIRListView(generic.ObjectListView): class RIRView(generic.ObjectView): queryset = RIR.objects.all() - def get_extra_context(self, request, instance): - aggregates = Aggregate.objects.restrict(request.user, 'view').filter(rir=instance).annotate( - child_count=RawSQL('SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix', ()) - ) - aggregates_table = tables.AggregateTable(aggregates, user=request.user, exclude=('rir', 'utilization')) - aggregates_table.configure(request) - - return { - 'aggregates_table': aggregates_table, - } - @register_model_view(RIR, 'edit') class RIREditView(generic.ObjectEditView): @@ -232,22 +219,11 @@ class ASNView(generic.ObjectView): queryset = ASN.objects.all() def get_extra_context(self, request, instance): - # Gather assigned Sites sites = instance.sites.restrict(request.user, 'view') - sites_table = SiteTable(sites, user=request.user) - sites_table.configure(request) - - # Gather assigned Providers - providers = instance.providers.restrict(request.user, 'view').annotate( - count_circuits=count_related(Circuit, 'provider') - ) - providers_table = ProviderTable(providers, user=request.user) - providers_table.configure(request) + providers = instance.providers.restrict(request.user, 'view') return { - 'sites_table': sites_table, 'sites_count': sites.count(), - 'providers_table': providers_table, 'providers_count': providers.count(), } @@ -392,18 +368,6 @@ class RoleListView(generic.ObjectListView): class RoleView(generic.ObjectView): queryset = Role.objects.all() - def get_extra_context(self, request, instance): - prefixes = Prefix.objects.restrict(request.user, 'view').filter( - role=instance - ) - - prefixes_table = tables.PrefixTable(prefixes, user=request.user, exclude=('role', 'utilization')) - prefixes_table.configure(request) - - return { - 'prefixes_table': prefixes_table, - } - @register_model_view(Role, 'edit') class RoleEditView(generic.ObjectEditView): @@ -750,7 +714,6 @@ def get_extra_context(self, request, instance): return { 'parent_prefixes_table': parent_prefixes_table, 'duplicate_ips_table': duplicate_ips_table, - 'more_duplicate_ips': duplicate_ips.count() > 10, 'related_ips_table': related_ips_table, 'services': services, } @@ -888,17 +851,9 @@ def get_extra_context(self, request, instance): vlans_table.columns.show('pk') vlans_table.configure(request) - # Compile permissions list for rendering the object table - permissions = { - 'add': request.user.has_perm('ipam.add_vlan'), - 'change': request.user.has_perm('ipam.change_vlan'), - 'delete': request.user.has_perm('ipam.delete_vlan'), - } - return { 'vlans_count': vlans_count, 'vlans_table': vlans_table, - 'permissions': permissions, } @@ -954,11 +909,6 @@ class FHRPGroupView(generic.ObjectView): queryset = FHRPGroup.objects.all() def get_extra_context(self, request, instance): - # Get assigned IP addresses - ipaddress_table = tables.AssignedIPAddressesTable( - data=instance.ip_addresses.restrict(request.user, 'view'), - orderable=False - ) # Get assigned interfaces members_table = tables.FHRPGroupAssignmentTable( @@ -968,7 +918,6 @@ def get_extra_context(self, request, instance): members_table.columns.hide('group') return { - 'ipaddress_table': ipaddress_table, 'members_table': members_table, 'member_count': FHRPGroupAssignment.objects.filter(group=instance).count(), } @@ -1250,10 +1199,6 @@ class L2VPNView(generic.ObjectView): queryset = L2VPN.objects.all() def get_extra_context(self, request, instance): - terminations = L2VPNTermination.objects.restrict(request.user, 'view').filter(l2vpn=instance) - terminations_table = tables.L2VPNTerminationTable(terminations, user=request.user, exclude=('l2vpn', )) - terminations_table.configure(request) - import_targets_table = tables.RouteTargetTable( instance.import_targets.prefetch_related('tenant'), orderable=False @@ -1264,7 +1209,6 @@ def get_extra_context(self, request, instance): ) return { - 'terminations_table': terminations_table, 'import_targets_table': import_targets_table, 'export_targets_table': export_targets_table, } diff --git a/netbox/netbox/tables/tables.py b/netbox/netbox/tables/tables.py index 3a2e71084d..4060f0e482 100644 --- a/netbox/netbox/tables/tables.py +++ b/netbox/netbox/tables/tables.py @@ -4,6 +4,8 @@ from django.contrib.contenttypes.models import ContentType from django.core.exceptions import FieldDoesNotExist from django.db.models.fields.related import RelatedField +from django.urls import reverse +from django.urls.exceptions import NoReverseMatch from django.utils.safestring import mark_safe from django.utils.translation import gettext as _ from django_tables2.data import TableQuerysetData @@ -12,7 +14,7 @@ from extras.choices import CustomFieldVisibilityChoices from netbox.tables import columns from utilities.paginator import EnhancedPaginator, get_paginate_count -from utilities.utils import highlight_string, title +from utilities.utils import get_viewname, highlight_string, title __all__ = ( 'BaseTable', @@ -197,6 +199,19 @@ def __init__(self, *args, extra_columns=None, **kwargs): super().__init__(*args, extra_columns=extra_columns, **kwargs) + @property + def htmx_url(self): + """ + Return the base HTML request URL for embedded tables. + """ + if getattr(self, 'embedded', False): + viewname = get_viewname(self._meta.model, action='list') + try: + return reverse(viewname) + except NoReverseMatch: + pass + return '' + class SearchTable(tables.Table): object_type = columns.ContentTypeColumn( diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 6060475d88..325d103387 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -20,7 +20,7 @@ from utilities.error_handlers import handle_protectederror from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation from utilities.forms import BulkRenameForm, ConfirmationForm, ImportForm, restrict_form_fields -from utilities.htmx import is_htmx +from utilities.htmx import is_embedded, is_htmx from utilities.permissions import get_permission_for_model from utilities.views import GetReturnURLMixin from .base import BaseMultiObjectView @@ -161,6 +161,11 @@ def get(self, request): # If this is an HTMX request, return only the rendered table HTML if is_htmx(request): + if is_embedded(request): + table.embedded = True + # Hide selection checkboxes + if 'pk' in table.base_columns: + table.columns.hide('pk') return render(request, 'htmx/table.html', { 'table': table, }) diff --git a/netbox/templates/circuits/circuittype.html b/netbox/templates/circuits/circuittype.html index c2ab235e44..4cefecc87c 100644 --- a/netbox/templates/circuits/circuittype.html +++ b/netbox/templates/circuits/circuittype.html @@ -31,7 +31,7 @@
Circuits - {{ circuits_table.rows|length }} + {{ object.circuits.count }} @@ -49,10 +49,10 @@
Circuits
-
- {% render_table circuits_table 'inc/table.html' %} - {% include 'inc/paginator.html' with paginator=circuits_table.paginator page=circuits_table.page %} -
+
{% plugin_full_width_page object %}
diff --git a/netbox/templates/circuits/provider.html b/netbox/templates/circuits/provider.html index 51f9113501..8cd7e59fba 100644 --- a/netbox/templates/circuits/provider.html +++ b/netbox/templates/circuits/provider.html @@ -40,7 +40,7 @@
Provider
Circuits - {{ circuits_table.rows|length }} + {{ object.circuits.count }} @@ -60,10 +60,10 @@
Provider
Circuits
-
- {% render_table circuits_table 'inc/table.html' %} - {% include 'inc/paginator.html' with paginator=circuits_table.paginator page=circuits_table.page %} -
+
{% plugin_full_width_page object %}
diff --git a/netbox/templates/circuits/providernetwork.html b/netbox/templates/circuits/providernetwork.html index 4987722a54..29c31ab472 100644 --- a/netbox/templates/circuits/providernetwork.html +++ b/netbox/templates/circuits/providernetwork.html @@ -50,10 +50,10 @@
Circuits
-
- {% render_table circuits_table 'inc/table.html' %} - {% include 'inc/paginator.html' with paginator=circuits_table.paginator page=circuits_table.page %} -
+
{% plugin_full_width_page object %}
diff --git a/netbox/templates/dcim/connections_list.html b/netbox/templates/dcim/connections_list.html index ef8bef828f..0d67dcaf08 100644 --- a/netbox/templates/dcim/connections_list.html +++ b/netbox/templates/dcim/connections_list.html @@ -12,7 +12,7 @@
{% include 'inc/table_controls_htmx.html' %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/device/consoleports.html b/netbox/templates/dcim/device/consoleports.html index 1f7cd037e9..ccd12f61c8 100644 --- a/netbox/templates/dcim/device/consoleports.html +++ b/netbox/templates/dcim/device/consoleports.html @@ -10,7 +10,7 @@ {% csrf_token %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/device/consoleserverports.html b/netbox/templates/dcim/device/consoleserverports.html index 259a072b43..43396651d2 100644 --- a/netbox/templates/dcim/device/consoleserverports.html +++ b/netbox/templates/dcim/device/consoleserverports.html @@ -10,7 +10,7 @@ {% csrf_token %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/device/devicebays.html b/netbox/templates/dcim/device/devicebays.html index 5081b752ba..9453b9a59a 100644 --- a/netbox/templates/dcim/device/devicebays.html +++ b/netbox/templates/dcim/device/devicebays.html @@ -10,7 +10,7 @@ {% csrf_token %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/device/frontports.html b/netbox/templates/dcim/device/frontports.html index 044337d007..dd0767d954 100644 --- a/netbox/templates/dcim/device/frontports.html +++ b/netbox/templates/dcim/device/frontports.html @@ -10,7 +10,7 @@ {% csrf_token %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/device/interfaces.html b/netbox/templates/dcim/device/interfaces.html index 9de486a6fe..c0e9a38b63 100644 --- a/netbox/templates/dcim/device/interfaces.html +++ b/netbox/templates/dcim/device/interfaces.html @@ -10,7 +10,7 @@ {% csrf_token %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/device/inventory.html b/netbox/templates/dcim/device/inventory.html index 065fd92f61..9e11031ec1 100644 --- a/netbox/templates/dcim/device/inventory.html +++ b/netbox/templates/dcim/device/inventory.html @@ -10,7 +10,7 @@ {% csrf_token %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/device/modulebays.html b/netbox/templates/dcim/device/modulebays.html index 6358a38157..7f0aacf1f2 100644 --- a/netbox/templates/dcim/device/modulebays.html +++ b/netbox/templates/dcim/device/modulebays.html @@ -10,7 +10,7 @@ {% csrf_token %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/device/poweroutlets.html b/netbox/templates/dcim/device/poweroutlets.html index 35a9795d57..66b21b7afb 100644 --- a/netbox/templates/dcim/device/poweroutlets.html +++ b/netbox/templates/dcim/device/poweroutlets.html @@ -10,7 +10,7 @@ {% csrf_token %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/device/powerports.html b/netbox/templates/dcim/device/powerports.html index 69485c9851..d9e1e121a3 100644 --- a/netbox/templates/dcim/device/powerports.html +++ b/netbox/templates/dcim/device/powerports.html @@ -10,7 +10,7 @@ {% csrf_token %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/device/rearports.html b/netbox/templates/dcim/device/rearports.html index 109e195dcc..ce194cc787 100644 --- a/netbox/templates/dcim/device/rearports.html +++ b/netbox/templates/dcim/device/rearports.html @@ -10,7 +10,7 @@ {% csrf_token %}
-
+
{% include 'htmx/table.html' %}
diff --git a/netbox/templates/dcim/devicerole.html b/netbox/templates/dcim/devicerole.html index 6724333d91..2e0794582d 100644 --- a/netbox/templates/dcim/devicerole.html +++ b/netbox/templates/dcim/devicerole.html @@ -45,14 +45,14 @@
Devices - {{ device_count }} + {{ object.devices.count }} Virtual Machines {% if object.vm_role %} - {{ virtualmachine_count }} + {{ object.virtual_machines.count }} {% else %} {{ ''|placeholder }} {% endif %} diff --git a/netbox/templates/dcim/devicetype/component_templates.html b/netbox/templates/dcim/devicetype/component_templates.html index 002a2044b8..ca552a5555 100644 --- a/netbox/templates/dcim/devicetype/component_templates.html +++ b/netbox/templates/dcim/devicetype/component_templates.html @@ -8,7 +8,7 @@ {% csrf_token %}
{{ title }}
-
+
{% include 'htmx/table.html' %}