From 56f404b8899fe6ec5a22b49f6dc5964c8b8f54e7 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 10 Oct 2022 11:04:39 -0400 Subject: [PATCH] Determine search categories from model app by default --- netbox/circuits/search.py | 21 +++++----- netbox/dcim/search.py | 69 ++++++++++++++++---------------- netbox/extras/search.py | 14 ++----- netbox/ipam/search.py | 45 ++++++++++----------- netbox/netbox/search/__init__.py | 13 ++++++ netbox/netbox/search/backends.py | 2 +- netbox/netbox/search/models.py | 5 --- netbox/netbox/search/register.py | 3 +- netbox/tenancy/search.py | 15 ++++--- netbox/virtualization/search.py | 15 ++++--- netbox/wireless/search.py | 15 ++++--- 11 files changed, 107 insertions(+), 110 deletions(-) delete mode 100644 netbox/netbox/search/models.py diff --git a/netbox/circuits/search.py b/netbox/circuits/search.py index 8c40acaaa..5adfb97fb 100644 --- a/netbox/circuits/search.py +++ b/netbox/circuits/search.py @@ -1,35 +1,34 @@ import circuits.filtersets import circuits.tables from circuits.models import Circuit, Provider, ProviderNetwork -from netbox.search.models import SearchMixin -from netbox.search import register_search +from netbox.search import SearchIndex, register_search from utilities.utils import count_related -@register_search(Provider) -class ProviderIndex(SearchMixin): +@register_search() +class ProviderIndex(SearchIndex): + model = Provider queryset = Provider.objects.annotate(count_circuits=count_related(Circuit, 'provider')) filterset = circuits.filtersets.ProviderFilterSet table = circuits.tables.ProviderTable url = 'circuits:provider_list' - choice_header = 'Circuits' -@register_search(Circuit) -class CircuitIndex(SearchMixin): +@register_search() +class CircuitIndex(SearchIndex): + model = Circuit queryset = Circuit.objects.prefetch_related( 'type', 'provider', 'tenant', 'tenant__group', 'terminations__site' ) filterset = circuits.filtersets.CircuitFilterSet table = circuits.tables.CircuitTable url = 'circuits:circuit_list' - choice_header = 'Circuits' -@register_search(ProviderNetwork) -class ProviderNetworkIndex(SearchMixin): +@register_search() +class ProviderNetworkIndex(SearchIndex): + model = ProviderNetwork queryset = ProviderNetwork.objects.prefetch_related('provider') filterset = circuits.filtersets.ProviderNetworkFilterSet table = circuits.tables.ProviderNetworkTable url = 'circuits:providernetwork_list' - choice_header = 'Circuits' diff --git a/netbox/dcim/search.py b/netbox/dcim/search.py index 2fbe8c322..b179402ce 100644 --- a/netbox/dcim/search.py +++ b/netbox/dcim/search.py @@ -13,42 +13,42 @@ from dcim.models import ( Site, VirtualChassis, ) -from netbox.search.models import SearchMixin -from netbox.search import register_search +from netbox.search import SearchIndex, register_search from utilities.utils import count_related -@register_search(Site) -class SiteIndex(SearchMixin): +@register_search() +class SiteIndex(SearchIndex): + model = Site queryset = Site.objects.prefetch_related('region', 'tenant', 'tenant__group') filterset = dcim.filtersets.SiteFilterSet table = dcim.tables.SiteTable url = 'dcim:site_list' - choice_header = 'DCIM' -@register_search(Rack) -class RackIndex(SearchMixin): +@register_search() +class RackIndex(SearchIndex): + model = Rack queryset = Rack.objects.prefetch_related('site', 'location', 'tenant', 'tenant__group', 'role').annotate( device_count=count_related(Device, 'rack') ) filterset = dcim.filtersets.RackFilterSet table = dcim.tables.RackTable url = 'dcim:rack_list' - choice_header = 'DCIM' -@register_search(RackReservation) -class RackReservationIndex(SearchMixin): +@register_search() +class RackReservationIndex(SearchIndex): + model = RackReservation queryset = RackReservation.objects.prefetch_related('rack', 'user') filterset = dcim.filtersets.RackReservationFilterSet table = dcim.tables.RackReservationTable url = 'dcim:rackreservation_list' - choice_header = 'DCIM' -@register_search(Location) -class LocationIndex(SearchMixin): +@register_search() +class LocationIndex(SearchIndex): + model = Location queryset = Location.objects.add_related_count( Location.objects.add_related_count(Location.objects.all(), Device, 'location', 'device_count', cumulative=True), Rack, @@ -59,22 +59,22 @@ class LocationIndex(SearchMixin): filterset = dcim.filtersets.LocationFilterSet table = dcim.tables.LocationTable url = 'dcim:location_list' - choice_header = 'DCIM' -@register_search(DeviceType) -class DeviceTypeIndex(SearchMixin): +@register_search() +class DeviceTypeIndex(SearchIndex): + model = DeviceType queryset = DeviceType.objects.prefetch_related('manufacturer').annotate( instance_count=count_related(Device, 'device_type') ) filterset = dcim.filtersets.DeviceTypeFilterSet table = dcim.tables.DeviceTypeTable url = 'dcim:devicetype_list' - choice_header = 'DCIM' -@register_search(Device) -class DeviceIndex(SearchMixin): +@register_search() +class DeviceIndex(SearchIndex): + model = Device queryset = Device.objects.prefetch_related( 'device_type__manufacturer', 'device_role', @@ -88,22 +88,22 @@ class DeviceIndex(SearchMixin): filterset = dcim.filtersets.DeviceFilterSet table = dcim.tables.DeviceTable url = 'dcim:device_list' - choice_header = 'DCIM' -@register_search(ModuleType) -class ModuleTypeIndex(SearchMixin): +@register_search() +class ModuleTypeIndex(SearchIndex): + model = ModuleType queryset = ModuleType.objects.prefetch_related('manufacturer').annotate( instance_count=count_related(Module, 'module_type') ) filterset = dcim.filtersets.ModuleTypeFilterSet table = dcim.tables.ModuleTypeTable url = 'dcim:moduletype_list' - choice_header = 'DCIM' -@register_search(Module) -class ModuleIndex(SearchMixin): +@register_search() +class ModuleIndex(SearchIndex): + model = Module queryset = Module.objects.prefetch_related( 'module_type__manufacturer', 'device', @@ -112,33 +112,32 @@ class ModuleIndex(SearchMixin): filterset = dcim.filtersets.ModuleFilterSet table = dcim.tables.ModuleTable url = 'dcim:module_list' - choice_header = 'DCIM' -@register_search(VirtualChassis) -class VirtualChassisIndex(SearchMixin): +@register_search() +class VirtualChassisIndex(SearchIndex): + model = VirtualChassis queryset = VirtualChassis.objects.prefetch_related('master').annotate( member_count=count_related(Device, 'virtual_chassis') ) filterset = dcim.filtersets.VirtualChassisFilterSet table = dcim.tables.VirtualChassisTable url = 'dcim:virtualchassis_list' - choice_header = 'DCIM' -@register_search(Cable) -class CableIndex(SearchMixin): +@register_search() +class CableIndex(SearchIndex): + model = Cable queryset = Cable.objects.all() filterset = dcim.filtersets.CableFilterSet table = dcim.tables.CableTable url = 'dcim:cable_list' - choice_header = 'DCIM' -@register_search(PowerFeed) -class PowerFeedIndex(SearchMixin): +@register_search() +class PowerFeedIndex(SearchIndex): + model = PowerFeed queryset = PowerFeed.objects.all() filterset = dcim.filtersets.PowerFeedFilterSet table = dcim.tables.PowerFeedTable url = 'dcim:powerfeed_list' - choice_header = 'DCIM' diff --git a/netbox/extras/search.py b/netbox/extras/search.py index 1da562275..ae6c9e7b9 100644 --- a/netbox/extras/search.py +++ b/netbox/extras/search.py @@ -1,20 +1,14 @@ import extras.filtersets import extras.tables -from django.db import models from extras.models import JournalEntry -from netbox.search.models import SearchMixin -from utilities.utils import count_related +from netbox.search import SearchIndex, register_search -class JournalEntryIndex(SearchMixin): +@register_search() +class JournalEntryIndex(SearchIndex): model = JournalEntry queryset = JournalEntry.objects.prefetch_related('assigned_object', 'created_by') filterset = extras.filtersets.JournalEntryFilterSet table = extras.tables.JournalEntryTable url = 'extras:journalentry_list' - choice_header = 'Journal' - - -JOURNAL_SEARCH_TYPES = { - 'journalentry': JournalEntryIndex, -} + category = 'Journal' diff --git a/netbox/ipam/search.py b/netbox/ipam/search.py index 4701fa07c..2f4599321 100644 --- a/netbox/ipam/search.py +++ b/netbox/ipam/search.py @@ -1,70 +1,69 @@ import ipam.filtersets import ipam.tables from ipam.models import ASN, VLAN, VRF, Aggregate, IPAddress, Prefix, Service -from netbox.search.models import SearchMixin -from netbox.search import register_search +from netbox.search import SearchIndex, register_search -@register_search(VRF) -class VRFIndex(SearchMixin): +@register_search() +class VRFIndex(SearchIndex): + model = VRF queryset = VRF.objects.prefetch_related('tenant', 'tenant__group') filterset = ipam.filtersets.VRFFilterSet table = ipam.tables.VRFTable url = 'ipam:vrf_list' - choice_header = 'IPAM' -@register_search(Aggregate) -class AggregateIndex(SearchMixin): +@register_search() +class AggregateIndex(SearchIndex): + model = Aggregate queryset = Aggregate.objects.prefetch_related('rir') filterset = ipam.filtersets.AggregateFilterSet table = ipam.tables.AggregateTable url = 'ipam:aggregate_list' - choice_header = 'IPAM' -@register_search(Prefix) -class PrefixIndex(SearchMixin): +@register_search() +class PrefixIndex(SearchIndex): + model = Prefix queryset = Prefix.objects.prefetch_related( 'site', 'vrf__tenant', 'tenant', 'tenant__group', 'vlan', 'role' ) filterset = ipam.filtersets.PrefixFilterSet table = ipam.tables.PrefixTable url = 'ipam:prefix_list' - choice_header = 'IPAM' -@register_search(IPAddress) -class IPAddressIndex(SearchMixin): +@register_search() +class IPAddressIndex(SearchIndex): + model = IPAddress queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant', 'tenant__group') filterset = ipam.filtersets.IPAddressFilterSet table = ipam.tables.IPAddressTable url = 'ipam:ipaddress_list' - choice_header = 'IPAM' -@register_search(VLAN) -class VLANIndex(SearchMixin): +@register_search() +class VLANIndex(SearchIndex): + model = VLAN queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'tenant__group', 'role') filterset = ipam.filtersets.VLANFilterSet table = ipam.tables.VLANTable url = 'ipam:vlan_list' - choice_header = 'IPAM' -@register_search(ASN) -class ASNIndex(SearchMixin): +@register_search() +class ASNIndex(SearchIndex): + model = ASN queryset = ASN.objects.prefetch_related('rir', 'tenant', 'tenant__group') filterset = ipam.filtersets.ASNFilterSet table = ipam.tables.ASNTable url = 'ipam:asn_list' - choice_header = 'IPAM' -@register_search(Service) -class ServiceIndex(SearchMixin): +@register_search() +class ServiceIndex(SearchIndex): + model = Service queryset = Service.objects.prefetch_related('device', 'virtual_machine') filterset = ipam.filtersets.ServiceFilterSet table = ipam.tables.ServiceTable url = 'ipam:service_list' - choice_header = 'IPAM' diff --git a/netbox/netbox/search/__init__.py b/netbox/netbox/search/__init__.py index 67d9d9344..261db8903 100644 --- a/netbox/netbox/search/__init__.py +++ b/netbox/netbox/search/__init__.py @@ -1 +1,14 @@ from .register import register_search + + +class SearchIndex: + """ + Base class for building search indexes. + """ + search_index = True + + @classmethod + def get_category(cls): + if hasattr(cls, 'category'): + return cls.category + return cls.model._meta.app_config.verbose_name diff --git a/netbox/netbox/search/backends.py b/netbox/netbox/search/backends.py index f769e4fa6..0aa025d9a 100644 --- a/netbox/netbox/search/backends.py +++ b/netbox/netbox/search/backends.py @@ -93,7 +93,7 @@ class SearchBackend(object): for name, cls in models.items(): model = cls.queryset.model title = model._meta.verbose_name.title() - categories[cls.choice_header][name] = title + categories[cls.get_category()][name] = title # Compile a nested tuple of choices for form rendering results = ( diff --git a/netbox/netbox/search/models.py b/netbox/netbox/search/models.py deleted file mode 100644 index 1a862a5f3..000000000 --- a/netbox/netbox/search/models.py +++ /dev/null @@ -1,5 +0,0 @@ -class SearchMixin(object): - """ - Base class for building search indexes. - """ - search_index = True diff --git a/netbox/netbox/search/register.py b/netbox/netbox/search/register.py index 14c4f239f..470aa290a 100644 --- a/netbox/netbox/search/register.py +++ b/netbox/netbox/search/register.py @@ -44,8 +44,9 @@ def register(): default_search_engine.register(cls_name, cls_obj) -def register_search(model): +def register_search(): def _wrapper(cls): + model = cls.model app_label = model._meta.app_label model_name = model._meta.model_name diff --git a/netbox/tenancy/search.py b/netbox/tenancy/search.py index 502a7606a..e52b1859e 100644 --- a/netbox/tenancy/search.py +++ b/netbox/tenancy/search.py @@ -1,26 +1,25 @@ import tenancy.filtersets import tenancy.tables -from netbox.search.models import SearchMixin -from netbox.search import register_search +from netbox.search import SearchIndex, register_search from tenancy.models import Contact, ContactAssignment, Tenant from utilities.utils import count_related -@register_search(Tenant) -class TenantIndex(SearchMixin): +@register_search() +class TenantIndex(SearchIndex): + model = Tenant queryset = Tenant.objects.prefetch_related('group') filterset = tenancy.filtersets.TenantFilterSet table = tenancy.tables.TenantTable url = 'tenancy:tenant_list' - choice_header = 'Tenancy' -@register_search(Contact) -class ContactIndex(SearchMixin): +@register_search() +class ContactIndex(SearchIndex): + model = Contact queryset = Contact.objects.prefetch_related('group', 'assignments').annotate( assignment_count=count_related(ContactAssignment, 'contact') ) filterset = tenancy.filtersets.ContactFilterSet table = tenancy.tables.ContactTable url = 'tenancy:contact_list' - choice_header = 'Tenancy' diff --git a/netbox/virtualization/search.py b/netbox/virtualization/search.py index a42ca1929..5b24f7fa0 100644 --- a/netbox/virtualization/search.py +++ b/netbox/virtualization/search.py @@ -1,25 +1,25 @@ import virtualization.filtersets import virtualization.tables from dcim.models import Device -from netbox.search.models import SearchMixin -from netbox.search import register_search +from netbox.search import SearchIndex, register_search from utilities.utils import count_related from virtualization.models import Cluster, VirtualMachine -@register_search(Cluster) -class ClusterIndex(SearchMixin): +@register_search() +class ClusterIndex(SearchIndex): + model = Cluster queryset = Cluster.objects.prefetch_related('type', 'group').annotate( device_count=count_related(Device, 'cluster'), vm_count=count_related(VirtualMachine, 'cluster') ) filterset = virtualization.filtersets.ClusterFilterSet table = virtualization.tables.ClusterTable url = 'virtualization:cluster_list' - choice_header = 'Virtualization' -@register_search(VirtualMachine) -class VirtualMachineIndex(SearchMixin): +@register_search() +class VirtualMachineIndex(SearchIndex): + model = VirtualMachine queryset = VirtualMachine.objects.prefetch_related( 'cluster', 'tenant', @@ -31,4 +31,3 @@ class VirtualMachineIndex(SearchMixin): filterset = virtualization.filtersets.VirtualMachineFilterSet table = virtualization.tables.VirtualMachineTable url = 'virtualization:virtualmachine_list' - choice_header = 'Virtualization' diff --git a/netbox/wireless/search.py b/netbox/wireless/search.py index a45244896..89ac23af8 100644 --- a/netbox/wireless/search.py +++ b/netbox/wireless/search.py @@ -1,27 +1,26 @@ import wireless.filtersets import wireless.tables from dcim.models import Interface -from netbox.search.models import SearchMixin -from netbox.search import register_search +from netbox.search import SearchIndex, register_search from utilities.utils import count_related from wireless.models import WirelessLAN, WirelessLink -@register_search(WirelessLAN) -class WirelessLANIndex(SearchMixin): +@register_search() +class WirelessLANIndex(SearchIndex): + model = WirelessLAN queryset = WirelessLAN.objects.prefetch_related('group', 'vlan').annotate( interface_count=count_related(Interface, 'wireless_lans') ) filterset = wireless.filtersets.WirelessLANFilterSet table = wireless.tables.WirelessLANTable url = 'wireless:wirelesslan_list' - choice_header = 'Wireless' -@register_search(WirelessLink) -class WirelessLinkIndex(SearchMixin): +@register_search() +class WirelessLinkIndex(SearchIndex): + model = WirelessLink queryset = WirelessLink.objects.prefetch_related('interface_a__device', 'interface_b__device') filterset = wireless.filtersets.WirelessLinkFilterSet table = wireless.tables.WirelessLinkTable url = 'wireless:wirelesslink_list' - choice_header = 'Wireless'