Enable HTMX for all ObjectChildrenViews

This commit is contained in:
jeremystretch 2021-12-14 15:31:42 -05:00
parent 402136dc8f
commit 4ffa823ab8
23 changed files with 290 additions and 104 deletions

View File

@ -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'

View File

@ -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):

View File

@ -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,

View File

@ -6,10 +6,14 @@
{% block content %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls.html' with table_modal="DeviceConsolePortTable_config" %}
<div class="table-responsive">
{% render_table table 'inc/table.html' %}
{% include 'inc/table_controls_htmx.html' with table_modal="DeviceConsolePortTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.dcim.change_consoleport %}
@ -38,6 +42,5 @@
{% endif %}
</div>
</form>
{% include 'inc/paginator.html' with paginator=table.paginator page=table.page %}
{% table_config_form table %}
{% endblock %}

View File

@ -6,10 +6,14 @@
{% block content %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls.html' with table_modal="DeviceConsoleServerPortTable_config" %}
<div class="table-responsive">
{% render_table table 'inc/table.html' %}
{% include 'inc/table_controls_htmx.html' with table_modal="DeviceConsoleServerPortTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.dcim.change_consoleserverport %}

View File

@ -6,10 +6,14 @@
{% block content %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls.html' with table_modal="DeviceDeviceBayTable_config" %}
<div class="table-responsive">
{% render_table table 'inc/table.html' %}
{% include 'inc/table_controls_htmx.html' with table_modal="DeviceDeviceBayTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.dcim.change_devicebay %}

View File

@ -6,10 +6,14 @@
{% block content %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls.html' with table_modal="DeviceFrontPortTable_config" %}
<div class="table-responsive">
{% render_table table 'inc/table.html' %}
{% include 'inc/table_controls_htmx.html' with table_modal="DeviceFrontPortTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.dcim.change_frontport %}

View File

@ -9,7 +9,15 @@
<div class="row mb-3 justify-content-between">
<div class="col col-12 col-lg-4 my-3 my-lg-0 d-flex noprint table-controls">
<div class="input-group input-group-sm">
<input type="text" class="form-control interface-filter" placeholder="Filter" title="Filter text (regular expressions supported)" />
<input
type="text"
name="q"
class="form-control"
placeholder="Quick search"
hx-get="{{ request.full_path }}"
hx-target="#object_list"
hx-trigger="keyup changed delay:500ms"
/>
</div>
</div>
<div class="col col-md-3 mb-0 d-flex noprint table-controls">
@ -34,9 +42,13 @@
</div>
</div>
</div>
<div class="table-responsive">
{% render_table table 'inc/table.html' %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.dcim.change_interface %}

View File

@ -6,10 +6,14 @@
{% block content %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls.html' with table_modal="DeviceInventoryItemTable_config" %}
<div class="table-responsive">
{% render_table table 'inc/table.html' %}
{% include 'inc/table_controls_htmx.html' with table_modal="DeviceInventoryItemTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.dcim.change_inventoryitem %}

View File

@ -6,10 +6,14 @@
{% block content %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls.html' with table_modal="DevicePowerOutletTable_config" %}
<div class="table-responsive">
{% render_table table 'inc/table.html' %}
{% include 'inc/table_controls_htmx.html' with table_modal="DevicePowerOutletTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.dcim.change_powerport %}

View File

@ -6,10 +6,14 @@
{% block content %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls.html' with table_modal="DevicePowerPortTable_config" %}
<div class="table-responsive">
{% render_table table 'inc/table.html' %}
{% include 'inc/table_controls_htmx.html' with table_modal="DevicePowerPortTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.dcim.change_powerport %}

View File

@ -6,10 +6,14 @@
{% block content %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls.html' with table_modal="DeviceRearPortTable_config" %}
<div class="table-responsive">
{% render_table table 'inc/table.html' %}
{% include 'inc/table_controls_htmx.html' with table_modal="DeviceRearPortTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.dcim.change_rearport %}

View File

@ -7,11 +7,9 @@
<form method="post">
{% csrf_token %}
<div class="card">
<h5 class="card-header">
{{ title }}
</h5>
<div class="card-body table-responsive">
{% render_table table 'inc/table.html' %}
<h5 class="card-header">{{ title }}</h5>
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
<div class="card-footer noprint">
{% if table.rows %}
@ -37,12 +35,10 @@
</form>
{% else %}
<div class="card">
<h5 class="card-header">
{{ title }}
</h5>
<div class="card-body table-responsive">
{% render_table table 'inc/table.html' %}
</div>
<h5 class="card-header">{{ title }}</h5>
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
{% endif %}
{% endblock content %}

View File

@ -1,4 +1,5 @@
{% extends 'ipam/iprange/base.html' %}
{% load helpers %}
{% block extra_controls %}
{% if perms.ipam.add_ipaddress and active_tab == 'ip-addresses' and object.first_available_ip %}
@ -9,9 +10,30 @@
{% endblock %}
{% block content %}
<div class="row">
<div class="col col-md-12">
{% include 'utilities/obj_table.html' with heading='IP Addresses' bulk_edit_url='ipam:ipaddress_bulk_edit' bulk_delete_url='ipam:ipaddress_bulk_delete' %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls_htmx.html' with table_modal="IPAddressTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.ipam.change_ipaddress %}
<button type="submit" name="_edit" formaction="{% url 'ipam:ipaddress_bulk_edit' %}?return_url={% url 'ipam:iprange_ipaddresses' pk=object.pk %}" class="btn btn-warning btn-sm">
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
</button>
{% endif %}
{% if perms.ipam.delete_ipaddress %}
<button type="submit" name="_delete" formaction="{% url 'ipam:ipaddress_bulk_delete' %}?return_url={% url 'ipam:iprange_ipaddresses' pk=object.pk %}" class="btn btn-danger btn-sm">
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
</button>
{% endif %}
</div>
</div>
</form>
{% table_config_form table %}
{% endblock %}

View File

@ -1,6 +1,5 @@
{% extends 'ipam/prefix/base.html' %}
{% load helpers %}
{% load static %}
{% block extra_controls %}
{% if perms.ipam.add_ipaddress and first_available_ip %}
@ -11,11 +10,30 @@
{% endblock %}
{% block content %}
<div class="row">
<div class="col col-md-12">
{% include 'inc/table_controls.html' with table_modal="IPAddressTable_config" %}
{% include 'utilities/obj_table.html' with heading='IP Addresses' bulk_edit_url='ipam:ipaddress_bulk_edit' bulk_delete_url='ipam:ipaddress_bulk_delete' %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls_htmx.html' with table_modal="IPAddressTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
</div>
{% table_config_form table table_name="IPAddressTable" %}
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.ipam.change_ipaddress %}
<button type="submit" name="_edit" formaction="{% url 'ipam:ipaddress_bulk_edit' %}?return_url={% url 'ipam:prefix_ipaddresses' pk=object.pk %}" class="btn btn-warning btn-sm">
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
</button>
{% endif %}
{% if perms.ipam.delete_ipaddress %}
<button type="submit" name="_delete" formaction="{% url 'ipam:ipaddress_bulk_delete' %}?return_url={% url 'ipam:prefix_ipaddresses' pk=object.pk %}" class="btn btn-danger btn-sm">
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
</button>
{% endif %}
</div>
</div>
</form>
{% table_config_form table %}
{% endblock %}

View File

@ -1,13 +1,31 @@
{% extends 'ipam/prefix/base.html' %}
{% load helpers %}
{% load static %}
{% block content %}
<div class="row">
<div class="col col-md-12">
{% include 'inc/table_controls.html' with table_modal="IPRangeTable_config" %}
{% include 'utilities/obj_table.html' with heading='Child IP Ranges' bulk_edit_url='ipam:iprange_bulk_edit' bulk_delete_url='ipam:iprange_bulk_delete' parent=prefix %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls_htmx.html' with table_modal="IPRangeTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
</div>
{% table_config_form table table_name="IPRangeTable" %}
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.ipam.change_iprange %}
<button type="submit" name="_edit" formaction="{% url 'ipam:iprange_bulk_edit' %}?return_url={% url 'ipam:prefix_ipranges' pk=object.pk %}" class="btn btn-warning btn-sm">
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
</button>
{% endif %}
{% if perms.ipam.delete_iprange %}
<button type="submit" name="_delete" formaction="{% url 'ipam:iprange_bulk_delete' %}?return_url={% url 'ipam:prefix_ipranges' pk=object.pk %}" class="btn btn-danger btn-sm">
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
</button>
{% endif %}
</div>
</div>
</form>
{% table_config_form table %}
{% endblock %}

View File

@ -1,6 +1,5 @@
{% extends 'ipam/prefix/base.html' %}
{% load helpers %}
{% load static %}
{% block extra_controls %}
{% include 'ipam/inc/toggle_available.html' %}
@ -13,11 +12,30 @@
{% endblock %}
{% block content %}
<div class="row">
<div class="col col-md-12">
{% include 'inc/table_controls.html' with table_modal="PrefixTable_config" %}
{% include 'utilities/obj_table.html' with heading='Child Prefixes' bulk_edit_url='ipam:prefix_bulk_edit' bulk_delete_url='ipam:prefix_bulk_delete' parent=prefix %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls_htmx.html' with table_modal="PrefixTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
</div>
{% table_config_form table table_name="PrefixTable" %}
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.ipam.change_prefix %}
<button type="submit" name="_edit" formaction="{% url 'ipam:prefix_bulk_edit' %}?return_url={% url 'ipam:prefix_prefixes' pk=object.pk %}" class="btn btn-warning btn-sm">
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
</button>
{% endif %}
{% if perms.ipam.delete_prefix %}
<button type="submit" name="_delete" formaction="{% url 'ipam:prefix_bulk_delete' %}?return_url={% url 'ipam:prefix_prefixes' pk=object.pk %}" class="btn btn-danger btn-sm">
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
</button>
{% endif %}
</div>
</div>
</form>
{% table_config_form table %}
{% endblock %}

View File

@ -1,9 +1,17 @@
{% extends 'ipam/vlan/base.html' %}
{% load helpers %}
{% block content %}
<div class="row">
<div class="col col-md-12">
{% include 'utilities/obj_table.html' with heading='Device Interfaces' parent=vlan %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls_htmx.html' with table_modal="VLANDevicesTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
</div>
</form>
{% table_config_form table %}
{% endblock %}

View File

@ -1,9 +1,17 @@
{% extends 'ipam/vlan/base.html' %}
{% load helpers %}
{% block content %}
<div class="row">
<div class="col col-md-12">
{% include 'utilities/obj_table.html' with heading='Virtual Machine Interfaces' parent=vlan %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls_htmx.html' with table_modal="VLANVirtualMachinesTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
</div>
</form>
{% table_config_form table %}
{% endblock %}

View File

@ -3,26 +3,25 @@
{% load render_table from django_tables2 %}
{% block content %}
<div class="row">
<div class="col col-md-12">
<form action="{% url 'virtualization:cluster_remove_devices' pk=object.pk %}" method="post">
{% csrf_token %}
{% include 'inc/table_controls_htmx.html' with table_modal="DeviceTable_config" %}
<div class="card">
<h5 class="card-header">
Host Devices
</h5>
<form action="{% url 'virtualization:cluster_remove_devices' pk=object.pk %}" method="post">
{% csrf_token %}
<div class="card-body table-responsive">
{% render_table table 'inc/table.html' %}
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
{% if perms.virtualization.change_cluster %}
<div class="card-footer noprint">
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.virtualization.change_cluster %}
<button type="submit" name="_remove" class="btn btn-danger btn-sm">
<span class="mdi mdi-trash-can-outline" aria-hidden="true"></span> Remove Devices
</button>
</div>
{% endif %}
</form>
{% endif %}
</div>
</div>
</div>
</div>
</form>
{% table_config_form table %}
{% endblock %}

View File

@ -3,16 +3,30 @@
{% load render_table from django_tables2 %}
{% block content %}
<div class="row">
<div class="col col-md-12">
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls_htmx.html' with table_modal="VirtualMachineTable_config" %}
<div class="card">
<h5 class="card-header">
Virtual Machines
</h5>
<div class="card-body table-responsive">
{% render_table table 'inc/table.html' %}
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
</div>
</div>
<div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.virtualization.change_virtualmachine %}
<button type="submit" name="_edit" formaction="{% url 'virtualization:virtualmachine_bulk_edit' %}?return_url={% url 'virtualization:cluster_virtualmachines' pk=object.pk %}" class="btn btn-warning btn-sm">
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
</button>
{% endif %}
{% if perms.virtualization.delete_virtualmachine %}
<button type="submit" name="_delete" formaction="{% url 'virtualization:virtualmachine_bulk_delete' %}?return_url={% url 'virtualization:cluster_virtualmachines' pk=object.pk %}" class="btn btn-danger btn-sm">
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
</button>
{% endif %}
</div>
</div>
</form>
{% table_config_form table %}
{% endblock %}

View File

@ -1,15 +1,18 @@
{% extends 'virtualization/virtualmachine/base.html' %}
{% load render_table from django_tables2 %}
{% load helpers %}
{% load static %}
{% block content %}
<form method="post">
{% csrf_token %}
{% include 'inc/table_controls.html' with table_modal="VirtualMachineVMInterfaceTable_config" %}
<div class="table-responsive">
{% render_table table 'inc/table.html' %}
{% include 'inc/table_controls_htmx.html' with table_modal="VMInterfaceTable_config" %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
<div class="noprint">
{% if perms.virtualization.change_vminterface %}
<button type="submit" name="_rename" formaction="{% url 'virtualization:vminterface_bulk_rename' %}?return_url={% url 'virtualization:virtualmachine_interfaces' pk=object.pk %}" class="btn btn-warning btn-sm">

View File

@ -4,6 +4,7 @@ from django.db.models import Prefetch
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from dcim.filtersets import DeviceFilterSet
from dcim.models import Device
from dcim.tables import DeviceTable
from extras.views import ObjectConfigContextView
@ -165,6 +166,7 @@ class ClusterVirtualMachinesView(generic.ObjectChildrenView):
queryset = Cluster.objects.all()
child_model = VirtualMachine
table = tables.VirtualMachineTable
filterset = filtersets.VirtualMachineFilterSet
template_name = 'virtualization/cluster/virtual_machines.html'
def get_children(self, request, parent):
@ -180,6 +182,7 @@ class ClusterDevicesView(generic.ObjectChildrenView):
queryset = Cluster.objects.all()
child_model = Device
table = DeviceTable
filterset = DeviceFilterSet
template_name = 'virtualization/cluster/devices.html'
def get_children(self, request, parent):
@ -345,6 +348,7 @@ class VirtualMachineInterfacesView(generic.ObjectChildrenView):
queryset = VirtualMachine.objects.all()
child_model = VMInterface
table = tables.VMInterfaceTable
filterset = filtersets.VMInterfaceFilterSet
template_name = 'virtualization/virtualmachine/interfaces.html'
def get_children(self, request, parent):