Просмотр исходного кода

Moves related ips to a tab (#12502)

* moves related ips to a tab #12233

* Refactor IP address templates to use a base template

---------

Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
Abhimanyu Saharan 2 лет назад
Родитель
Сommit
6b19f15a7b

+ 8 - 0
netbox/ipam/models/ip.py

@@ -783,6 +783,14 @@ class IPAddress(PrimaryModel):
                 if available_ips:
                     return next(iter(available_ips))
 
+    def get_related_ips(self):
+        """
+        Return all IPAddresses belonging to the same VRF.
+        """
+        return IPAddress.objects.exclude(address=str(self.address)).filter(
+            vrf=self.vrf, address__net_contained_or_equal=str(self.address)
+        )
+
     def clean(self):
         super().clean()
 

+ 18 - 10
netbox/ipam/views.py

@@ -755,19 +755,9 @@ class IPAddressView(generic.ObjectView):
         # Limit to a maximum of 10 duplicates displayed here
         duplicate_ips_table = tables.IPAddressTable(duplicate_ips[:10], orderable=False)
 
-        # Related IP table
-        related_ips = IPAddress.objects.restrict(request.user, 'view').exclude(
-            address=str(instance.address)
-        ).filter(
-            vrf=instance.vrf, address__net_contained_or_equal=str(instance.address)
-        )
-        related_ips_table = tables.IPAddressTable(related_ips, orderable=False)
-        related_ips_table.configure(request)
-
         return {
             'parent_prefixes_table': parent_prefixes_table,
             'duplicate_ips_table': duplicate_ips_table,
-            'related_ips_table': related_ips_table,
         }
 
 
@@ -872,6 +862,24 @@ class IPAddressBulkDeleteView(generic.BulkDeleteView):
     table = tables.IPAddressTable
 
 
+@register_model_view(IPAddress, 'related_ips', path='related-ip-addresses')
+class IPAddressRelatedIPsView(generic.ObjectChildrenView):
+    queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant')
+    child_model = IPAddress
+    table = tables.IPAddressTable
+    filterset = filtersets.IPAddressFilterSet
+    template_name = 'ipam/ipaddress/ip_addresses.html'
+    tab = ViewTab(
+        label=_('Related IPs'),
+        badge=lambda x: x.get_related_ips().count(),
+        weight=500,
+        hide_if_empty=True,
+    )
+
+    def get_children(self, request, parent):
+        return parent.get_related_ips().restrict(request.user, 'view')
+
+
 #
 # VLAN groups
 #

+ 0 - 8
netbox/templates/ipam/ipaddress.html

@@ -3,13 +3,6 @@
 {% load plugins %}
 {% load render_table from django_tables2 %}
 
-{% block breadcrumbs %}
-  {{ block.super }}
-  {% if object.vrf %}
-    <li class="breadcrumb-item"><a href="{% url 'ipam:ipaddress_list' %}?vrf_id={{ object.vrf.pk }}">{{ object.vrf }}</a></li>
-  {% endif %}
-{% endblock %}
-
 {% block content %}
 <div class="row">
 	<div class="col col-md-4">
@@ -116,7 +109,6 @@
     {% if duplicate_ips_table.rows %}
       {% include 'inc/panel_table.html' with table=duplicate_ips_table heading='Duplicate IPs' panel_class='danger' %}
     {% endif %}
-    {% include 'inc/panel_table.html' with table=related_ips_table heading='Related IPs' %}
     <div class="card">
       <h5 class="card-header">Services</h5>
       <div class="card-body htmx-container table-responsive"

+ 8 - 0
netbox/templates/ipam/ipaddress/base.html

@@ -0,0 +1,8 @@
+{% extends 'generic/object.html' %}
+
+{% block breadcrumbs %}
+  {{ block.super }}
+  {% if object.vrf %}
+    <li class="breadcrumb-item"><a href="{% url 'ipam:ipaddress_list' %}?vrf_id={{ object.vrf.pk }}">{{ object.vrf }}</a></li>
+  {% endif %}
+{% endblock %}

+ 19 - 0
netbox/templates/ipam/ipaddress/ip_addresses.html

@@ -0,0 +1,19 @@
+{% extends 'ipam/ipaddress/base.html' %}
+{% load helpers %}
+
+{% block content %}
+    {% include 'inc/table_controls_htmx.html' with table_modal="IPAddressTable_config" %}
+    <form method="post">
+        {% csrf_token %}
+        <div class="card">
+            <div class="card-body" id="object_list">
+                {% include 'htmx/table.html' %}
+            </div>
+        </div>
+    </form>
+{% endblock content %}
+
+{% block modals %}
+    {{ block.super }}
+    {% table_config_form table %}
+{% endblock modals %}