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

Replace active_tab context for object views

jeremystretch 3 лет назад
Родитель
Сommit
5e1a0733e4

+ 0 - 9
netbox/dcim/views.py

@@ -46,11 +46,6 @@ class DeviceComponentsView(generic.ObjectChildrenView):
     def get_children(self, request, parent):
     def get_children(self, request, parent):
         return self.child_model.objects.restrict(request.user, 'view').filter(device=parent)
         return self.child_model.objects.restrict(request.user, 'view').filter(device=parent)
 
 
-    def get_extra_context(self, request, instance):
-        return {
-            'active_tab': f"{self.child_model._meta.verbose_name_plural.replace(' ', '')}",
-        }
-
 
 
 class DeviceTypeComponentsView(DeviceComponentsView):
 class DeviceTypeComponentsView(DeviceComponentsView):
     queryset = DeviceType.objects.all()
     queryset = DeviceType.objects.all()
@@ -61,9 +56,7 @@ class DeviceTypeComponentsView(DeviceComponentsView):
         return self.child_model.objects.restrict(request.user, 'view').filter(device_type=parent)
         return self.child_model.objects.restrict(request.user, 'view').filter(device_type=parent)
 
 
     def get_extra_context(self, request, instance):
     def get_extra_context(self, request, instance):
-        model_name = self.child_model._meta.verbose_name_plural
         return {
         return {
-            'active_tab': f"{model_name.replace(' ', '').replace('template', '')}",
             'return_url': reverse(self.viewname, kwargs={'pk': instance.pk}),
             'return_url': reverse(self.viewname, kwargs={'pk': instance.pk}),
         }
         }
 
 
@@ -77,9 +70,7 @@ class ModuleTypeComponentsView(DeviceComponentsView):
         return self.child_model.objects.restrict(request.user, 'view').filter(module_type=parent)
         return self.child_model.objects.restrict(request.user, 'view').filter(module_type=parent)
 
 
     def get_extra_context(self, request, instance):
     def get_extra_context(self, request, instance):
-        model_name = self.child_model._meta.verbose_name_plural
         return {
         return {
-            'active_tab': f"{model_name.replace(' ', '').replace('template', '')}",
             'return_url': reverse(self.viewname, kwargs={'pk': instance.pk}),
             'return_url': reverse(self.viewname, kwargs={'pk': instance.pk}),
         }
         }
 
 

+ 0 - 1
netbox/extras/views.py

@@ -352,7 +352,6 @@ class ObjectConfigContextView(generic.ObjectView):
             'source_contexts': source_contexts,
             'source_contexts': source_contexts,
             'format': format,
             'format': format,
             'base_template': self.base_template,
             'base_template': self.base_template,
-            'active_tab': 'configcontext',
         }
         }
 
 
 
 

+ 0 - 2
netbox/ipam/urls.py

@@ -141,8 +141,6 @@ urlpatterns = [
     path('vlans/edit/', views.VLANBulkEditView.as_view(), name='vlan_bulk_edit'),
     path('vlans/edit/', views.VLANBulkEditView.as_view(), name='vlan_bulk_edit'),
     path('vlans/delete/', views.VLANBulkDeleteView.as_view(), name='vlan_bulk_delete'),
     path('vlans/delete/', views.VLANBulkDeleteView.as_view(), name='vlan_bulk_delete'),
     path('vlans/<int:pk>/', views.VLANView.as_view(), name='vlan'),
     path('vlans/<int:pk>/', views.VLANView.as_view(), name='vlan'),
-    path('vlans/<int:pk>/interfaces/', views.VLANInterfacesView.as_view(), name='vlan_interfaces'),
-    path('vlans/<int:pk>/vm-interfaces/', views.VLANVMInterfacesView.as_view(), name='vlan_vminterfaces'),
     path('vlans/<int:pk>/edit/', views.VLANEditView.as_view(), name='vlan_edit'),
     path('vlans/<int:pk>/edit/', views.VLANEditView.as_view(), name='vlan_edit'),
     path('vlans/<int:pk>/delete/', views.VLANDeleteView.as_view(), name='vlan_delete'),
     path('vlans/<int:pk>/delete/', views.VLANDeleteView.as_view(), name='vlan_delete'),
     path('vlans/<int:pk>/', include(get_model_urls('ipam', 'vlan'))),
     path('vlans/<int:pk>/', include(get_model_urls('ipam', 'vlan'))),

+ 12 - 19
netbox/ipam/views.py

@@ -319,7 +319,6 @@ class AggregatePrefixesView(generic.ObjectChildrenView):
     def get_extra_context(self, request, instance):
     def get_extra_context(self, request, instance):
         return {
         return {
             'bulk_querystring': f'within={instance.prefix}',
             'bulk_querystring': f'within={instance.prefix}',
-            'active_tab': 'prefixes',
             'first_available_prefix': instance.get_first_available_prefix(),
             'first_available_prefix': instance.get_first_available_prefix(),
             'show_available': bool(request.GET.get('show_available', 'true') == 'true'),
             'show_available': bool(request.GET.get('show_available', 'true') == 'true'),
             'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'),
             'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'),
@@ -502,7 +501,6 @@ class PrefixPrefixesView(generic.ObjectChildrenView):
     def get_extra_context(self, request, instance):
     def get_extra_context(self, request, instance):
         return {
         return {
             'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&within={instance.prefix}",
             'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&within={instance.prefix}",
-            'active_tab': 'prefixes',
             'first_available_prefix': instance.get_first_available_prefix(),
             'first_available_prefix': instance.get_first_available_prefix(),
             'show_available': bool(request.GET.get('show_available', 'true') == 'true'),
             'show_available': bool(request.GET.get('show_available', 'true') == 'true'),
             'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'),
             'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'),
@@ -530,7 +528,6 @@ class PrefixIPRangesView(generic.ObjectChildrenView):
     def get_extra_context(self, request, instance):
     def get_extra_context(self, request, instance):
         return {
         return {
             'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}",
             'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}",
-            'active_tab': 'ipranges',
             'first_available_ip': instance.get_first_available_ip(),
             'first_available_ip': instance.get_first_available_ip(),
         }
         }
 
 
@@ -559,7 +556,6 @@ class PrefixIPAddressesView(generic.ObjectChildrenView):
     def get_extra_context(self, request, instance):
     def get_extra_context(self, request, instance):
         return {
         return {
             'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}",
             'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}",
-            'active_tab': 'ipaddresses',
             'first_available_ip': instance.get_first_available_ip(),
             'first_available_ip': instance.get_first_available_ip(),
         }
         }
 
 
@@ -623,11 +619,6 @@ class IPRangeIPAddressesView(generic.ObjectChildrenView):
     def get_children(self, request, parent):
     def get_children(self, request, parent):
         return parent.get_child_ips().restrict(request.user, 'view')
         return parent.get_child_ips().restrict(request.user, 'view')
 
 
-    def get_extra_context(self, request, instance):
-        return {
-            'active_tab': 'ipaddresses',
-        }
-
 
 
 class IPRangeEditView(generic.ObjectEditView):
 class IPRangeEditView(generic.ObjectEditView):
     queryset = IPRange.objects.all()
     queryset = IPRange.objects.all()
@@ -1032,37 +1023,39 @@ class VLANView(generic.ObjectView):
         }
         }
 
 
 
 
+@register_model_view(VLAN, 'interfaces')
 class VLANInterfacesView(generic.ObjectChildrenView):
 class VLANInterfacesView(generic.ObjectChildrenView):
     queryset = VLAN.objects.all()
     queryset = VLAN.objects.all()
     child_model = Interface
     child_model = Interface
     table = tables.VLANDevicesTable
     table = tables.VLANDevicesTable
     filterset = InterfaceFilterSet
     filterset = InterfaceFilterSet
     template_name = 'ipam/vlan/interfaces.html'
     template_name = 'ipam/vlan/interfaces.html'
+    tab = ViewTab(
+        label=_('Device Interfaces'),
+        badge=lambda x: x.get_interfaces().count(),
+        permission='dcim.view_interface'
+    )
 
 
     def get_children(self, request, parent):
     def get_children(self, request, parent):
         return parent.get_interfaces().restrict(request.user, 'view')
         return parent.get_interfaces().restrict(request.user, 'view')
 
 
-    def get_extra_context(self, request, instance):
-        return {
-            'active_tab': 'interfaces',
-        }
-
 
 
+@register_model_view(VLAN, 'vminterfaces', path='vm-interfaces')
 class VLANVMInterfacesView(generic.ObjectChildrenView):
 class VLANVMInterfacesView(generic.ObjectChildrenView):
     queryset = VLAN.objects.all()
     queryset = VLAN.objects.all()
     child_model = VMInterface
     child_model = VMInterface
     table = tables.VLANVirtualMachinesTable
     table = tables.VLANVirtualMachinesTable
     filterset = VMInterfaceFilterSet
     filterset = VMInterfaceFilterSet
     template_name = 'ipam/vlan/vminterfaces.html'
     template_name = 'ipam/vlan/vminterfaces.html'
+    tab = ViewTab(
+        label=_('VM Interfaces'),
+        badge=lambda x: x.get_vminterfaces().count(),
+        permission='virtualization.view_vminterface'
+    )
 
 
     def get_children(self, request, parent):
     def get_children(self, request, parent):
         return parent.get_vminterfaces().restrict(request.user, 'view')
         return parent.get_vminterfaces().restrict(request.user, 'view')
 
 
-    def get_extra_context(self, request, instance):
-        return {
-            'active_tab': 'vminterfaces',
-        }
-
 
 
 class VLANEditView(generic.ObjectEditView):
 class VLANEditView(generic.ObjectEditView):
     queryset = VLAN.objects.all()
     queryset = VLAN.objects.all()

+ 1 - 0
netbox/netbox/views/generic/base.py

@@ -14,6 +14,7 @@ class BaseObjectView(ObjectPermissionRequiredMixin, View):
     """
     """
     queryset = None
     queryset = None
     template_name = None
     template_name = None
+    tab = None
 
 
     def get_object(self, **kwargs):
     def get_object(self, **kwargs):
         """
         """

+ 2 - 2
netbox/netbox/views/generic/feature_views.py

@@ -62,7 +62,7 @@ class ObjectChangeLogView(View):
             'object': obj,
             'object': obj,
             'table': objectchanges_table,
             'table': objectchanges_table,
             'base_template': self.base_template,
             'base_template': self.base_template,
-            'active_tab': 'changelog',
+            'tab': self.tab,
         })
         })
 
 
 
 
@@ -122,5 +122,5 @@ class ObjectJournalView(View):
             'form': form,
             'form': form,
             'table': journalentry_table,
             'table': journalentry_table,
             'base_template': self.base_template,
             'base_template': self.base_template,
-            'active_tab': 'journal',
+            'tab': self.tab,
         })
         })

+ 2 - 1
netbox/netbox/views/generic/object_views.py

@@ -5,7 +5,6 @@ from django.contrib import messages
 from django.core.exceptions import ObjectDoesNotExist
 from django.core.exceptions import ObjectDoesNotExist
 from django.db import transaction
 from django.db import transaction
 from django.db.models import ProtectedError
 from django.db.models import ProtectedError
-from django.forms.widgets import HiddenInput
 from django.shortcuts import redirect, render
 from django.shortcuts import redirect, render
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.html import escape
 from django.utils.html import escape
@@ -67,6 +66,7 @@ class ObjectView(BaseObjectView):
 
 
         return render(request, self.get_template_name(), {
         return render(request, self.get_template_name(), {
             'object': instance,
             'object': instance,
+            'tab': self.tab,
             **self.get_extra_context(request, instance),
             **self.get_extra_context(request, instance),
         })
         })
 
 
@@ -141,6 +141,7 @@ class ObjectChildrenView(ObjectView, ActionsMixin, TableMixin):
             'child_model': self.child_model,
             'child_model': self.child_model,
             'table': table,
             'table': table,
             'actions': actions,
             'actions': actions,
+            'tab': self.tab,
             **self.get_extra_context(request, instance),
             **self.get_extra_context(request, instance),
         })
         })
 
 

+ 1 - 1
netbox/templates/generic/object.html

@@ -81,7 +81,7 @@ Context:
   <ul class="nav nav-tabs px-3">
   <ul class="nav nav-tabs px-3">
     {# Primary tab #}
     {# Primary tab #}
     <li class="nav-item" role="presentation">
     <li class="nav-item" role="presentation">
-      <a class="nav-link{% if not active_tab %} active{% endif %}" href="{{ object.get_absolute_url }}">{{ object|meta:"verbose_name"|bettertitle }}</a>
+      <a class="nav-link{% if not tab %} active{% endif %}" href="{{ object.get_absolute_url }}">{{ object|meta:"verbose_name"|bettertitle }}</a>
     </li>
     </li>
 
 
     {# Include any extra tabs passed by the view #}
     {# Include any extra tabs passed by the view #}

+ 0 - 24
netbox/templates/ipam/vlan/base.html

@@ -13,27 +13,3 @@
     <li class="breadcrumb-item"><a href="{% url 'ipam:vlan_list' %}?group_id={{ object.group.pk }}">{{ object.group }}</a></li>
     <li class="breadcrumb-item"><a href="{% url 'ipam:vlan_list' %}?group_id={{ object.group.pk }}">{{ object.group }}</a></li>
   {% endif %}
   {% endif %}
 {% endblock %}
 {% endblock %}
-
-{% block tabs %}
-  <ul class="nav nav-tabs px-3">
-    <li class="nav-item" role="presentation">
-      <a class="nav-link{% if not active_tab %} active{% endif %}" href="{% url 'ipam:vlan' pk=object.pk %}">VLAN</a>
-    </li>
-    <li class="nav-item" role="presentation">
-      <a class="nav-link{% if active_tab == 'interfaces' %} active{% endif %}" href="{% url 'ipam:vlan_interfaces' pk=object.pk %}">Device Interfaces {% badge object.get_interfaces.count %}</a>
-    </li>
-    <li class="nav-item" role="presentation">
-      <a class="nav-link{% if active_tab == 'vminterfaces' %} active{% endif %}" href="{% url 'ipam:vlan_vminterfaces' pk=object.pk %}">VM Interfaces {% badge object.get_vminterfaces.count %}</a>
-    </li>
-    {% if perms.extras.view_journalentry %}
-      <li class="nav-item" role="presentation">
-        <a class="nav-link{% if active_tab == 'journal' %} active{% endif %}" href="{% url 'ipam:vlan_journal' pk=object.pk %}">Journal</a>
-      </li>
-    {% endif %}
-    {% if perms.extras.view_objectchange %}
-      <li class="nav-item" role="presentation">
-        <a class="nav-link{% if active_tab == 'changelog' %} active{% endif %}" href="{% url 'ipam:vlan_changelog' pk=object.pk %}">Change Log</a>
-      </li>
-    {% endif %}
-  </ul>
-{% endblock %}

+ 4 - 2
netbox/utilities/templatetags/tabs.py

@@ -41,12 +41,14 @@ def model_view_tabs(context, instance):
             if not tab.always_display and not badge_value:
             if not tab.always_display and not badge_value:
                 continue
                 continue
 
 
+            viewname = f"{app_label}:{model_name}_{config['name']}"
+            active_tab = context.get('tab')
             tabs.append({
             tabs.append({
                 'name': config['name'],
                 'name': config['name'],
-                'url': reverse(f"{app_label}:{model_name}_{config['name']}", args=[instance.pk]),
+                'url': reverse(viewname, args=[instance.pk]),
                 'label': tab.label,
                 'label': tab.label,
                 'badge_value': badge_value,
                 'badge_value': badge_value,
-                'is_active': context.get('active_tab') == config['name'],
+                'is_active': active_tab and active_tab == tab,
             })
             })
 
 
     return {
     return {

+ 0 - 15
netbox/virtualization/views.py

@@ -179,11 +179,6 @@ class ClusterVirtualMachinesView(generic.ObjectChildrenView):
     def get_children(self, request, parent):
     def get_children(self, request, parent):
         return VirtualMachine.objects.restrict(request.user, 'view').filter(cluster=parent)
         return VirtualMachine.objects.restrict(request.user, 'view').filter(cluster=parent)
 
 
-    def get_extra_context(self, request, instance):
-        return {
-            'active_tab': 'virtualmachines',
-        }
-
 
 
 @register_model_view(Cluster, 'devices')
 @register_model_view(Cluster, 'devices')
 class ClusterDevicesView(generic.ObjectChildrenView):
 class ClusterDevicesView(generic.ObjectChildrenView):
@@ -201,11 +196,6 @@ class ClusterDevicesView(generic.ObjectChildrenView):
     def get_children(self, request, parent):
     def get_children(self, request, parent):
         return Device.objects.restrict(request.user, 'view').filter(cluster=parent)
         return Device.objects.restrict(request.user, 'view').filter(cluster=parent)
 
 
-    def get_extra_context(self, request, instance):
-        return {
-            'active_tab': 'devices',
-        }
-
 
 
 class ClusterEditView(generic.ObjectEditView):
 class ClusterEditView(generic.ObjectEditView):
     queryset = Cluster.objects.all()
     queryset = Cluster.objects.all()
@@ -377,11 +367,6 @@ class VirtualMachineInterfacesView(generic.ObjectChildrenView):
             'tags',
             'tags',
         )
         )
 
 
-    def get_extra_context(self, request, instance):
-        return {
-            'active_tab': 'interfaces',
-        }
-
 
 
 @register_model_view(VirtualMachine, 'configcontext', path='config-context')
 @register_model_view(VirtualMachine, 'configcontext', path='config-context')
 class VirtualMachineConfigContextView(ObjectConfigContextView):
 class VirtualMachineConfigContextView(ObjectConfigContextView):