mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-25 00:36:11 -06:00
8927 get search choices working
This commit is contained in:
parent
c31d746494
commit
632fd99b2f
@ -12,6 +12,7 @@ class ProviderIndex(SearchMixin):
|
|||||||
filterset = circuits.filtersets.ProviderFilterSet
|
filterset = circuits.filtersets.ProviderFilterSet
|
||||||
table = circuits.tables.ProviderTable
|
table = circuits.tables.ProviderTable
|
||||||
url = 'circuits:provider_list'
|
url = 'circuits:provider_list'
|
||||||
|
choice_header = 'Circuits'
|
||||||
|
|
||||||
|
|
||||||
class CircuitIndex(SearchMixin):
|
class CircuitIndex(SearchMixin):
|
||||||
@ -22,6 +23,7 @@ class CircuitIndex(SearchMixin):
|
|||||||
filterset = circuits.filtersets.CircuitFilterSet
|
filterset = circuits.filtersets.CircuitFilterSet
|
||||||
table = circuits.tables.CircuitTable
|
table = circuits.tables.CircuitTable
|
||||||
url = 'circuits:circuit_list'
|
url = 'circuits:circuit_list'
|
||||||
|
choice_header = 'Circuits'
|
||||||
|
|
||||||
|
|
||||||
class ProviderNetworkIndex(SearchMixin):
|
class ProviderNetworkIndex(SearchMixin):
|
||||||
@ -30,6 +32,7 @@ class ProviderNetworkIndex(SearchMixin):
|
|||||||
filterset = circuits.filtersets.ProviderNetworkFilterSet
|
filterset = circuits.filtersets.ProviderNetworkFilterSet
|
||||||
table = circuits.tables.ProviderNetworkTable
|
table = circuits.tables.ProviderNetworkTable
|
||||||
url = 'circuits:providernetwork_list'
|
url = 'circuits:providernetwork_list'
|
||||||
|
choice_header = 'Circuits'
|
||||||
|
|
||||||
|
|
||||||
CIRCUIT_SEARCH_TYPES = {
|
CIRCUIT_SEARCH_TYPES = {
|
||||||
|
@ -25,6 +25,7 @@ class SiteIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.SiteFilterSet
|
filterset = dcim.filtersets.SiteFilterSet
|
||||||
table = dcim.tables.SiteTable
|
table = dcim.tables.SiteTable
|
||||||
url = 'dcim:site_list'
|
url = 'dcim:site_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
class RackIndex(SearchMixin):
|
class RackIndex(SearchMixin):
|
||||||
@ -35,6 +36,7 @@ class RackIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.RackFilterSet
|
filterset = dcim.filtersets.RackFilterSet
|
||||||
table = dcim.tables.RackTable
|
table = dcim.tables.RackTable
|
||||||
url = 'dcim:rack_list'
|
url = 'dcim:rack_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
class RackReservationIndex(SearchMixin):
|
class RackReservationIndex(SearchMixin):
|
||||||
@ -43,6 +45,7 @@ class RackReservationIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.RackReservationFilterSet
|
filterset = dcim.filtersets.RackReservationFilterSet
|
||||||
table = dcim.tables.RackReservationTable
|
table = dcim.tables.RackReservationTable
|
||||||
url = 'dcim:rackreservation_list'
|
url = 'dcim:rackreservation_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
class LocationIndex(SearchMixin):
|
class LocationIndex(SearchMixin):
|
||||||
@ -57,6 +60,7 @@ class LocationIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.LocationFilterSet
|
filterset = dcim.filtersets.LocationFilterSet
|
||||||
table = dcim.tables.LocationTable
|
table = dcim.tables.LocationTable
|
||||||
url = 'dcim:location_list'
|
url = 'dcim:location_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
class DeviceTypeIndex(SearchMixin):
|
class DeviceTypeIndex(SearchMixin):
|
||||||
@ -67,6 +71,7 @@ class DeviceTypeIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.DeviceTypeFilterSet
|
filterset = dcim.filtersets.DeviceTypeFilterSet
|
||||||
table = dcim.tables.DeviceTypeTable
|
table = dcim.tables.DeviceTypeTable
|
||||||
url = 'dcim:devicetype_list'
|
url = 'dcim:devicetype_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
class DeviceIndex(SearchMixin):
|
class DeviceIndex(SearchMixin):
|
||||||
@ -84,6 +89,7 @@ class DeviceIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.DeviceFilterSet
|
filterset = dcim.filtersets.DeviceFilterSet
|
||||||
table = dcim.tables.DeviceTable
|
table = dcim.tables.DeviceTable
|
||||||
url = 'dcim:device_list'
|
url = 'dcim:device_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
class ModuleTypeIndex(SearchMixin):
|
class ModuleTypeIndex(SearchMixin):
|
||||||
@ -94,6 +100,7 @@ class ModuleTypeIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.ModuleTypeFilterSet
|
filterset = dcim.filtersets.ModuleTypeFilterSet
|
||||||
table = dcim.tables.ModuleTypeTable
|
table = dcim.tables.ModuleTypeTable
|
||||||
url = 'dcim:moduletype_list'
|
url = 'dcim:moduletype_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
class ModuleIndex(SearchMixin):
|
class ModuleIndex(SearchMixin):
|
||||||
@ -106,6 +113,7 @@ class ModuleIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.ModuleFilterSet
|
filterset = dcim.filtersets.ModuleFilterSet
|
||||||
table = dcim.tables.ModuleTable
|
table = dcim.tables.ModuleTable
|
||||||
url = 'dcim:module_list'
|
url = 'dcim:module_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
class VirtualChassisIndex(SearchMixin):
|
class VirtualChassisIndex(SearchMixin):
|
||||||
@ -116,6 +124,7 @@ class VirtualChassisIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.VirtualChassisFilterSet
|
filterset = dcim.filtersets.VirtualChassisFilterSet
|
||||||
table = dcim.tables.VirtualChassisTable
|
table = dcim.tables.VirtualChassisTable
|
||||||
url = 'dcim:virtualchassis_list'
|
url = 'dcim:virtualchassis_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
class CableIndex(SearchMixin):
|
class CableIndex(SearchMixin):
|
||||||
@ -124,6 +133,7 @@ class CableIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.CableFilterSet
|
filterset = dcim.filtersets.CableFilterSet
|
||||||
table = dcim.tables.CableTable
|
table = dcim.tables.CableTable
|
||||||
url = 'dcim:cable_list'
|
url = 'dcim:cable_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
class PowerFeedIndex(SearchMixin):
|
class PowerFeedIndex(SearchMixin):
|
||||||
@ -132,6 +142,7 @@ class PowerFeedIndex(SearchMixin):
|
|||||||
filterset = dcim.filtersets.PowerFeedFilterSet
|
filterset = dcim.filtersets.PowerFeedFilterSet
|
||||||
table = dcim.tables.PowerFeedTable
|
table = dcim.tables.PowerFeedTable
|
||||||
url = 'dcim:powerfeed_list'
|
url = 'dcim:powerfeed_list'
|
||||||
|
choice_header = 'DCIM'
|
||||||
|
|
||||||
|
|
||||||
DCIM_SEARCH_TYPES = {
|
DCIM_SEARCH_TYPES = {
|
||||||
|
@ -12,6 +12,7 @@ class JournalEntryIndex(SearchMixin):
|
|||||||
filterset = extras.filtersets.JournalEntryFilterSet
|
filterset = extras.filtersets.JournalEntryFilterSet
|
||||||
table = extras.tables.JournalEntryTable
|
table = extras.tables.JournalEntryTable
|
||||||
url = 'extras:journalentry_list'
|
url = 'extras:journalentry_list'
|
||||||
|
choice_header = 'Journal'
|
||||||
|
|
||||||
|
|
||||||
JOURNAL_SEARCH_TYPES = {
|
JOURNAL_SEARCH_TYPES = {
|
||||||
|
@ -12,6 +12,7 @@ class VRFIndex(SearchMixin):
|
|||||||
filterset = ipam.filtersets.VRFFilterSet
|
filterset = ipam.filtersets.VRFFilterSet
|
||||||
table = ipam.tables.VRFTable
|
table = ipam.tables.VRFTable
|
||||||
url = 'ipam:vrf_list'
|
url = 'ipam:vrf_list'
|
||||||
|
choice_header = 'IPAM'
|
||||||
|
|
||||||
|
|
||||||
class AggregateIndex(SearchMixin):
|
class AggregateIndex(SearchMixin):
|
||||||
@ -20,6 +21,7 @@ class AggregateIndex(SearchMixin):
|
|||||||
filterset = ipam.filtersets.AggregateFilterSet
|
filterset = ipam.filtersets.AggregateFilterSet
|
||||||
table = ipam.tables.AggregateTable
|
table = ipam.tables.AggregateTable
|
||||||
url = 'ipam:aggregate_list'
|
url = 'ipam:aggregate_list'
|
||||||
|
choice_header = 'IPAM'
|
||||||
|
|
||||||
|
|
||||||
class PrefixIndex(SearchMixin):
|
class PrefixIndex(SearchMixin):
|
||||||
@ -30,6 +32,7 @@ class PrefixIndex(SearchMixin):
|
|||||||
filterset = ipam.filtersets.PrefixFilterSet
|
filterset = ipam.filtersets.PrefixFilterSet
|
||||||
table = ipam.tables.PrefixTable
|
table = ipam.tables.PrefixTable
|
||||||
url = 'ipam:prefix_list'
|
url = 'ipam:prefix_list'
|
||||||
|
choice_header = 'IPAM'
|
||||||
|
|
||||||
|
|
||||||
class IPAddressIndex(SearchMixin):
|
class IPAddressIndex(SearchMixin):
|
||||||
@ -38,6 +41,7 @@ class IPAddressIndex(SearchMixin):
|
|||||||
filterset = ipam.filtersets.IPAddressFilterSet
|
filterset = ipam.filtersets.IPAddressFilterSet
|
||||||
table = ipam.tables.IPAddressTable
|
table = ipam.tables.IPAddressTable
|
||||||
url = 'ipam:ipaddress_list'
|
url = 'ipam:ipaddress_list'
|
||||||
|
choice_header = 'IPAM'
|
||||||
|
|
||||||
|
|
||||||
class VLANIndex(SearchMixin):
|
class VLANIndex(SearchMixin):
|
||||||
@ -46,6 +50,7 @@ class VLANIndex(SearchMixin):
|
|||||||
filterset = ipam.filtersets.VLANFilterSet
|
filterset = ipam.filtersets.VLANFilterSet
|
||||||
table = ipam.tables.VLANTable
|
table = ipam.tables.VLANTable
|
||||||
url = 'ipam:vlan_list'
|
url = 'ipam:vlan_list'
|
||||||
|
choice_header = 'IPAM'
|
||||||
|
|
||||||
|
|
||||||
class ASNIndex(SearchMixin):
|
class ASNIndex(SearchMixin):
|
||||||
@ -54,6 +59,7 @@ class ASNIndex(SearchMixin):
|
|||||||
filterset = ipam.filtersets.ASNFilterSet
|
filterset = ipam.filtersets.ASNFilterSet
|
||||||
table = ipam.tables.ASNTable
|
table = ipam.tables.ASNTable
|
||||||
url = 'ipam:asn_list'
|
url = 'ipam:asn_list'
|
||||||
|
choice_header = 'IPAM'
|
||||||
|
|
||||||
|
|
||||||
class ServiceIndex(SearchMixin):
|
class ServiceIndex(SearchMixin):
|
||||||
@ -62,6 +68,7 @@ class ServiceIndex(SearchMixin):
|
|||||||
filterset = ipam.filtersets.ServiceFilterSet
|
filterset = ipam.filtersets.ServiceFilterSet
|
||||||
table = ipam.tables.ServiceTable
|
table = ipam.tables.ServiceTable
|
||||||
url = 'ipam:service_list'
|
url = 'ipam:service_list'
|
||||||
|
choice_header = 'IPAM'
|
||||||
|
|
||||||
|
|
||||||
IPAM_SEARCH_TYPES = {
|
IPAM_SEARCH_TYPES = {
|
||||||
|
@ -39,8 +39,8 @@ class SearchConfig(AppConfig):
|
|||||||
submodule_name = "search_indexes"
|
submodule_name = "search_indexes"
|
||||||
if module_has_submodule(module, submodule_name):
|
if module_has_submodule(module, submodule_name):
|
||||||
module_name = f"{name}.{submodule_name}"
|
module_name = f"{name}.{submodule_name}"
|
||||||
for cls_name, cls_obj in inspect.getmembers(sys.modules[module_name]):
|
for cls_name, cls_obj in inspect.getmembers(sys.modules[module_name], predicate=inspect.isclass):
|
||||||
if inspect.isclass(cls_obj) and getattr(cls_obj, "search_index", False) and getattr(cls_obj, "model", None):
|
if getattr(cls_obj, "search_index", False) and getattr(cls_obj, "model", None):
|
||||||
cls_name = cls_obj.model.__name__.lower()
|
cls_name = cls_obj.model.__name__.lower()
|
||||||
if not default_search_engine.is_registered(cls_name, cls_obj):
|
if not default_search_engine.is_registered(cls_name, cls_obj):
|
||||||
default_search_engine.register(cls_name, cls_obj)
|
default_search_engine.register(cls_name, cls_obj)
|
||||||
|
@ -20,7 +20,8 @@ class SearchBackend(object):
|
|||||||
"""A search engine capable of performing multi-table searches."""
|
"""A search engine capable of performing multi-table searches."""
|
||||||
|
|
||||||
_created_engines: dict = dict()
|
_created_engines: dict = dict()
|
||||||
_search_choices = tuple()
|
_search_choices = {}
|
||||||
|
_search_choice_options = tuple()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_created_engines(cls):
|
def get_created_engines(cls):
|
||||||
@ -57,6 +58,13 @@ class SearchBackend(object):
|
|||||||
|
|
||||||
self._registered_models[key] = model
|
self._registered_models[key] = model
|
||||||
|
|
||||||
|
# add to the search choices
|
||||||
|
if model.choice_header not in self._search_choices:
|
||||||
|
self._search_choices[model.choice_header] = {}
|
||||||
|
|
||||||
|
if key not in self._search_choices[model.choice_header]:
|
||||||
|
self._search_choices[model.choice_header][key] = model.queryset.model._meta.verbose_name_plural
|
||||||
|
|
||||||
# Connect to the signalling framework.
|
# Connect to the signalling framework.
|
||||||
if self._use_hooks():
|
if self._use_hooks():
|
||||||
post_save.connect(self._post_save_receiver, model)
|
post_save.connect(self._post_save_receiver, model)
|
||||||
@ -68,22 +76,21 @@ class SearchBackend(object):
|
|||||||
# Signalling hooks.
|
# Signalling hooks.
|
||||||
|
|
||||||
def get_search_choices(self):
|
def get_search_choices(self):
|
||||||
if self._search_choices:
|
if self._search_choice_options:
|
||||||
return self._search_choices
|
return self._search_choice_options
|
||||||
|
|
||||||
result = list()
|
result = list()
|
||||||
result.append(('', 'All Objects'))
|
result.append(('', 'All Objects'))
|
||||||
for category, items in self.get_registry().items():
|
for category, items in self._search_choices.items():
|
||||||
subcategories = list()
|
subcategories = list()
|
||||||
for slug, obj in items.items():
|
for slug, verbose_name in items.items():
|
||||||
name = obj.queryset.model._meta.verbose_name_plural
|
name = verbose_name
|
||||||
name = name[0].upper() + name[1:]
|
name = name[0].upper() + name[1:]
|
||||||
subcategories.append((slug, name))
|
subcategories.append((slug, name))
|
||||||
result.append((category, tuple(subcategories)))
|
result.append((category, tuple(subcategories)))
|
||||||
|
|
||||||
self._search_choices = tuple(result)
|
self._search_choice_options = tuple(result)
|
||||||
print(self._search_choices)
|
return self._search_choice_options
|
||||||
return self._search_choices
|
|
||||||
|
|
||||||
def _use_hooks(self):
|
def _use_hooks(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -7,23 +7,23 @@ from utilities.utils import count_related
|
|||||||
|
|
||||||
|
|
||||||
class TenantIndex(SearchMixin):
|
class TenantIndex(SearchMixin):
|
||||||
def __init__(self):
|
model = Tenant
|
||||||
self.model = Tenant
|
queryset = Tenant.objects.prefetch_related('group')
|
||||||
self.queryset = Tenant.objects.prefetch_related('group')
|
filterset = tenancy.filtersets.TenantFilterSet
|
||||||
self.filterset = tenancy.filtersets.TenantFilterSet
|
table = tenancy.tables.TenantTable
|
||||||
self.table = tenancy.tables.TenantTable
|
url = 'tenancy:tenant_list'
|
||||||
self.url = 'tenancy:tenant_list'
|
choice_header = 'Tenancy'
|
||||||
|
|
||||||
|
|
||||||
class ContactIndex(SearchMixin):
|
class ContactIndex(SearchMixin):
|
||||||
def __init__(self):
|
model = Contact
|
||||||
self.model = Contact
|
queryset = Contact.objects.prefetch_related('group', 'assignments').annotate(
|
||||||
self.queryset = Contact.objects.prefetch_related('group', 'assignments').annotate(
|
|
||||||
assignment_count=count_related(ContactAssignment, 'contact')
|
assignment_count=count_related(ContactAssignment, 'contact')
|
||||||
)
|
)
|
||||||
self.filterset = tenancy.filtersets.ContactFilterSet
|
filterset = tenancy.filtersets.ContactFilterSet
|
||||||
self.table = tenancy.tables.ContactTable
|
table = tenancy.tables.ContactTable
|
||||||
self.url = 'tenancy:contact_list'
|
url = 'tenancy:contact_list'
|
||||||
|
choice_header = 'Tenancy'
|
||||||
|
|
||||||
|
|
||||||
TENANCY_SEARCH_TYPES = {
|
TENANCY_SEARCH_TYPES = {
|
||||||
|
@ -7,20 +7,19 @@ from virtualization.models import Cluster, Device, VirtualMachine
|
|||||||
|
|
||||||
|
|
||||||
class ClusterIndex(SearchMixin):
|
class ClusterIndex(SearchMixin):
|
||||||
def __init__(self):
|
model = Cluster
|
||||||
self.model = Cluster
|
queryset = Cluster.objects.prefetch_related('type', 'group').annotate(
|
||||||
self.queryset = Cluster.objects.prefetch_related('type', 'group').annotate(
|
|
||||||
device_count=count_related(Device, 'cluster'), vm_count=count_related(VirtualMachine, 'cluster')
|
device_count=count_related(Device, 'cluster'), vm_count=count_related(VirtualMachine, 'cluster')
|
||||||
)
|
)
|
||||||
self.filterset = virtualization.filtersets.ClusterFilterSet
|
filterset = virtualization.filtersets.ClusterFilterSet
|
||||||
self.table = virtualization.tables.ClusterTable
|
table = virtualization.tables.ClusterTable
|
||||||
self.url = 'virtualization:cluster_list'
|
url = 'virtualization:cluster_list'
|
||||||
|
choice_header = 'Virtualization'
|
||||||
|
|
||||||
|
|
||||||
class VirtualMachineIndex(SearchMixin):
|
class VirtualMachineIndex(SearchMixin):
|
||||||
def __init__(self):
|
model = VirtualMachine
|
||||||
self.model = VirtualMachine
|
queryset = VirtualMachine.objects.prefetch_related(
|
||||||
self.queryset = VirtualMachine.objects.prefetch_related(
|
|
||||||
'cluster',
|
'cluster',
|
||||||
'tenant',
|
'tenant',
|
||||||
'tenant__group',
|
'tenant__group',
|
||||||
@ -28,9 +27,10 @@ class VirtualMachineIndex(SearchMixin):
|
|||||||
'primary_ip4',
|
'primary_ip4',
|
||||||
'primary_ip6',
|
'primary_ip6',
|
||||||
)
|
)
|
||||||
self.filterset = virtualization.filtersets.VirtualMachineFilterSet
|
filterset = virtualization.filtersets.VirtualMachineFilterSet
|
||||||
self.table = virtualization.tables.VirtualMachineTable
|
table = virtualization.tables.VirtualMachineTable
|
||||||
self.url = 'virtualization:virtualmachine_list'
|
url = 'virtualization:virtualmachine_list'
|
||||||
|
choice_header = 'Virtualization'
|
||||||
|
|
||||||
|
|
||||||
VIRTUALIZATION_SEARCH_TYPES = {
|
VIRTUALIZATION_SEARCH_TYPES = {
|
||||||
|
@ -15,6 +15,7 @@ class WirelessLANIndex(SearchMixin):
|
|||||||
filterset = wireless.filtersets.WirelessLANFilterSet
|
filterset = wireless.filtersets.WirelessLANFilterSet
|
||||||
table = wireless.tables.WirelessLANTable
|
table = wireless.tables.WirelessLANTable
|
||||||
url = 'wireless:wirelesslan_list'
|
url = 'wireless:wirelesslan_list'
|
||||||
|
choice_header = 'Wireless'
|
||||||
|
|
||||||
|
|
||||||
class WirelessLinkIndex(SearchMixin):
|
class WirelessLinkIndex(SearchMixin):
|
||||||
@ -23,6 +24,7 @@ class WirelessLinkIndex(SearchMixin):
|
|||||||
filterset = wireless.filtersets.WirelessLinkFilterSet
|
filterset = wireless.filtersets.WirelessLinkFilterSet
|
||||||
table = wireless.tables.WirelessLinkTable
|
table = wireless.tables.WirelessLinkTable
|
||||||
url = 'wireless:wirelesslink_list'
|
url = 'wireless:wirelesslink_list'
|
||||||
|
choice_header = 'Wireless'
|
||||||
|
|
||||||
|
|
||||||
WIRELESS_SEARCH_TYPES = {
|
WIRELESS_SEARCH_TYPES = {
|
||||||
|
Loading…
Reference in New Issue
Block a user