Quellcode durchsuchen

Fixes #10682: Correct home view links to connection lists

jeremystretch vor 3 Jahren
Ursprung
Commit
658c9347f3
3 geänderte Dateien mit 56 neuen und 63 gelöschten Zeilen
  1. 1 0
      docs/release-notes/version-3.3.md
  2. 53 61
      netbox/netbox/views/__init__.py
  3. 2 2
      netbox/templates/home.html

+ 1 - 0
docs/release-notes/version-3.3.md

@@ -19,6 +19,7 @@
 * [#10643](https://github.com/netbox-community/netbox/issues/10643) - Ensure consistent display of custom fields for all model forms
 * [#10646](https://github.com/netbox-community/netbox/issues/10646) - Fix filtering of power feed by power panel when connecting a cable
 * [#10655](https://github.com/netbox-community/netbox/issues/10655) - Correct display of assigned contacts in object tables
+* [#10682](https://github.com/netbox-community/netbox/issues/10682) - Correct home view links to connection lists
 * [#10712](https://github.com/netbox-community/netbox/issues/10712) - Fix ModuleNotFoundError exception when generating API schema under Python 3.9+
 * [#10716](https://github.com/netbox-community/netbox/issues/10716) - Add left/right page plugin content embeds for tag view
 * [#10719](https://github.com/netbox-community/netbox/issues/10719) - Prevent user without sufficient permission from creating an IP address via FHRP group creation

+ 53 - 61
netbox/netbox/views/__init__.py

@@ -1,5 +1,6 @@
 import platform
 import sys
+from collections import namedtuple
 
 from django.conf import settings
 from django.core.cache import cache
@@ -8,6 +9,7 @@ from django.shortcuts import redirect, render
 from django.template import loader
 from django.template.exceptions import TemplateDoesNotExist
 from django.urls import reverse
+from django.utils.translation import gettext as _
 from django.views.decorators.csrf import requires_csrf_token
 from django.views.defaults import ERROR_500_TEMPLATE_NAME, page_not_found
 from django.views.generic import View
@@ -24,100 +26,90 @@ from ipam.models import Aggregate, IPAddress, IPRange, Prefix, VLAN, VRF
 from netbox.constants import SEARCH_MAX_RESULTS
 from netbox.forms import SearchForm
 from netbox.search import SEARCH_TYPES
-from tenancy.models import Tenant
+from tenancy.models import Contact, Tenant
 from virtualization.models import Cluster, VirtualMachine
 from wireless.models import WirelessLAN, WirelessLink
 
 
+Link = namedtuple('Link', ('label', 'viewname', 'permission', 'count'))
+
+
 class HomeView(View):
     template_name = 'home.html'
 
     def get(self, request):
         if settings.LOGIN_REQUIRED and not request.user.is_authenticated:
-            return redirect("login")
+            return redirect('login')
 
-        connected_consoleports = ConsolePort.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
+        console_connections = ConsolePort.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
             _path__is_complete=True
-        )
-        connected_powerports = PowerPort.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
+        ).count
+        power_connections = PowerPort.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
             _path__is_complete=True
-        )
-        connected_interfaces = Interface.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
+        ).count
+        interface_connections = Interface.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
             _path__is_complete=True
-        )
+        ).count
+
+        def get_count_queryset(model):
+            return model.objects.restrict(request.user, 'view').count
 
         def build_stats():
             org = (
-                ("dcim.view_site", "Sites", Site.objects.restrict(request.user, 'view').count),
-                ("tenancy.view_tenant", "Tenants", Tenant.objects.restrict(request.user, 'view').count),
+                Link(_('Sites'), 'dcim:site_list', 'dcim.view_site', get_count_queryset(Site)),
+                Link(_('Tenants'), 'tenancy:tenant_list', 'tenancy.view_tenant', get_count_queryset(Tenant)),
+                Link(_('Contacts'), 'tenancy:contact_list', 'tenancy.view_contact', get_count_queryset(Contact)),
             )
             dcim = (
-                ("dcim.view_rack", "Racks", Rack.objects.restrict(request.user, 'view').count),
-                ("dcim.view_devicetype", "Device Types", DeviceType.objects.restrict(request.user, 'view').count),
-                ("dcim.view_device", "Devices", Device.objects.restrict(request.user, 'view').count),
+                Link(_('Racks'), 'dcim:rack_list', 'dcim.view_rack', get_count_queryset(Rack)),
+                Link(_('Device Types'), 'dcim:devicetype_list', 'dcim.view_devicetype', get_count_queryset(DeviceType)),
+                Link(_('Devices'), 'dcim:device_list', 'dcim.view_device', get_count_queryset(Device)),
             )
             ipam = (
-                ("ipam.view_vrf", "VRFs", VRF.objects.restrict(request.user, 'view').count),
-                ("ipam.view_aggregate", "Aggregates", Aggregate.objects.restrict(request.user, 'view').count),
-                ("ipam.view_prefix", "Prefixes", Prefix.objects.restrict(request.user, 'view').count),
-                ("ipam.view_iprange", "IP Ranges", IPRange.objects.restrict(request.user, 'view').count),
-                ("ipam.view_ipaddress", "IP Addresses", IPAddress.objects.restrict(request.user, 'view').count),
-                ("ipam.view_vlan", "VLANs", VLAN.objects.restrict(request.user, 'view').count)
-
+                Link(_('VRFs'), 'ipam:vrf_list', 'ipam.view_vrf', get_count_queryset(VRF)),
+                Link(_('Aggregates'), 'ipam:aggregate_list', 'ipam.view_aggregate', get_count_queryset(Aggregate)),
+                Link(_('Prefixes'), 'ipam:prefix_list', 'ipam.view_prefix', get_count_queryset(Prefix)),
+                Link(_('IP Ranges'), 'ipam:iprange_list', 'ipam.view_iprange', get_count_queryset(IPRange)),
+                Link(_('IP Addresses'), 'ipam:ipaddress_list', 'ipam.view_ipaddress', get_count_queryset(IPAddress)),
+                Link(_('VLANs'), 'ipam:vlan_list', 'ipam.view_vlan', get_count_queryset(VLAN)),
             )
             circuits = (
-                ("circuits.view_provider", "Providers", Provider.objects.restrict(request.user, 'view').count),
-                ("circuits.view_circuit", "Circuits", Circuit.objects.restrict(request.user, 'view').count),
+                Link(_('Providers'), 'circuits:provider_list', 'circuits.view_provider', get_count_queryset(Provider)),
+                Link(_('Circuits'), 'circuits:circuit_list', 'circuits.view_circuit', get_count_queryset(Circuit))
             )
             virtualization = (
-                ("virtualization.view_cluster", "Clusters", Cluster.objects.restrict(request.user, 'view').count),
-                ("virtualization.view_virtualmachine", "Virtual Machines", VirtualMachine.objects.restrict(request.user, 'view').count),
-
+                Link(_('Clusters'), 'virtualization:cluster_list', 'virtualization.view_cluster',
+                     get_count_queryset(Cluster)),
+                Link(_('Virtual Machines'), 'virtualization:virtualmachine_list', 'virtualization.view_virtualmachine',
+                     get_count_queryset(VirtualMachine)),
             )
             connections = (
-                ("dcim.view_cable", "Cables", Cable.objects.restrict(request.user, 'view').count),
-                ("dcim.view_consoleport", "Console", connected_consoleports.count),
-                ("dcim.view_interface", "Interfaces", connected_interfaces.count),
-                ("dcim.view_powerport", "Power Connections", connected_powerports.count),
+                Link(_('Cables'), 'dcim:cable_list', 'dcim.view_cable', get_count_queryset(Cable)),
+                Link(_('Interfaces'), 'dcim:interface_connections_list', 'dcim.view_interface', interface_connections),
+                Link(_('Console'), 'dcim:console_connections_list', 'dcim.view_consoleport', console_connections),
+                Link(_('Power'), 'dcim:power_connections_list', 'dcim.view_powerport', power_connections),
             )
             power = (
-                ("dcim.view_powerpanel", "Power Panels", PowerPanel.objects.restrict(request.user, 'view').count),
-                ("dcim.view_powerfeed", "Power Feeds", PowerFeed.objects.restrict(request.user, 'view').count),
+                Link(_('Power Panels'), 'dcim:powerpanel_list', 'dcim.view_powerpanel', get_count_queryset(PowerPanel)),
+                Link(_('Power Feeds'), 'dcim:powerfeed_list', 'dcim.view_powerfeed', get_count_queryset(PowerFeed)),
             )
             wireless = (
-                ("wireless.view_wirelesslan", "Wireless LANs", WirelessLAN.objects.restrict(request.user, 'view').count),
-                ("wireless.view_wirelesslink", "Wireless Links", WirelessLink.objects.restrict(request.user, 'view').count),
+                Link(_('Wireless LANs'), 'wireless:wirelesslan_list', 'wireless.view_wirelesslan',
+                     get_count_queryset(WirelessLAN)),
+                Link(_('Wireless Links'), 'wireless:wirelesslink_list', 'wireless.view_wirelesslink',
+                     get_count_queryset(WirelessLink)),
             )
-            sections = (
-                ("Organization", org, "domain"),
-                ("IPAM", ipam, "counter"),
-                ("Virtualization", virtualization, "monitor"),
-                ("Inventory", dcim, "server"),
-                ("Circuits", circuits, "transit-connection-variant"),
-                ("Connections", connections, "cable-data"),
-                ("Power", power, "flash"),
-                ("Wireless", wireless, "wifi"),
+            stats = (
+                (_('Organization'), org, 'domain'),
+                (_('IPAM'), ipam, 'counter'),
+                (_('Virtualization'), virtualization, 'monitor'),
+                (_('Inventory'), dcim, 'server'),
+                (_('Circuits'), circuits, 'transit-connection-variant'),
+                (_('Connections'), connections, 'cable-data'),
+                (_('Power'), power, 'flash'),
+                (_('Wireless'), wireless, 'wifi'),
             )
 
-            stats = []
-            for section_label, section_items, icon_class in sections:
-                items = []
-                for perm, item_label, get_count in section_items:
-                    app, scope = perm.split(".")
-                    url = ":".join((app, scope.replace("view_", "") + "_list"))
-                    item = {
-                        "label": item_label,
-                        "count": None,
-                        "url": url,
-                        "disabled": True,
-                        "icon": icon_class,
-                    }
-                    if request.user.has_perm(perm):
-                        item["count"] = get_count()
-                        item["disabled"] = False
-                    items.append(item)
-                stats.append((section_label, items, icon_class))
-
             return stats
 
         # Compile changelog table

+ 2 - 2
netbox/templates/home.html

@@ -36,8 +36,8 @@
             <div class="card-body">
               <div class="list-group list-group-flush">
                 {% for item in items %}
-                  {% if not item.disabled %}
-                    <a href="{% url item.url %}" class="list-group-item list-group-item-action">
+                  {% if item.permission in perms %}
+                    <a href="{% url item.viewname %}" class="list-group-item list-group-item-action">
                       <div class="d-flex w-100 justify-content-between align-items-center">
                         {{ item.label }}
                         <h4 class="mb-1">{{ item.count }}</h4>