Utilize global registry to register model search classes

This commit is contained in:
jeremystretch 2022-10-10 10:09:40 -04:00
parent 5797ba0fd7
commit e67965ae22
19 changed files with 76 additions and 125 deletions

View File

@ -6,4 +6,4 @@ class CircuitsConfig(AppConfig):
verbose_name = "Circuits"
def ready(self):
import circuits.signals
from . import signals, search

View File

@ -1,13 +1,13 @@
import circuits.filtersets
import circuits.tables
from circuits.models import Circuit, Provider, ProviderNetwork
from django.db import models
from netbox.search.models import SearchMixin
from netbox.search import register_search
from utilities.utils import count_related
@register_search(Provider)
class ProviderIndex(SearchMixin):
model = Provider
queryset = Provider.objects.annotate(count_circuits=count_related(Circuit, 'provider'))
filterset = circuits.filtersets.ProviderFilterSet
table = circuits.tables.ProviderTable
@ -15,8 +15,8 @@ class ProviderIndex(SearchMixin):
choice_header = 'Circuits'
@register_search(Circuit)
class CircuitIndex(SearchMixin):
model = Circuit
queryset = Circuit.objects.prefetch_related(
'type', 'provider', 'tenant', 'tenant__group', 'terminations__site'
)
@ -26,17 +26,10 @@ class CircuitIndex(SearchMixin):
choice_header = 'Circuits'
@register_search(ProviderNetwork)
class ProviderNetworkIndex(SearchMixin):
model = ProviderNetwork
queryset = ProviderNetwork.objects.prefetch_related('provider')
filterset = circuits.filtersets.ProviderNetworkFilterSet
table = circuits.tables.ProviderNetworkTable
url = 'circuits:providernetwork_list'
choice_header = 'Circuits'
CIRCUIT_SEARCH_TYPES = {
'provider': ProviderIndex,
'circuit': CircuitIndex,
'providernetwork': ProviderNetworkIndex,
}

View File

@ -8,7 +8,7 @@ class DCIMConfig(AppConfig):
verbose_name = "DCIM"
def ready(self):
import dcim.signals
from . import signals, search
from .models import CableTermination
# Register denormalized fields

View File

@ -14,11 +14,12 @@ from dcim.models import (
VirtualChassis,
)
from netbox.search.models import SearchMixin
from netbox.search import register_search
from utilities.utils import count_related
@register_search(Site)
class SiteIndex(SearchMixin):
model = Site
queryset = Site.objects.prefetch_related('region', 'tenant', 'tenant__group')
filterset = dcim.filtersets.SiteFilterSet
table = dcim.tables.SiteTable
@ -26,8 +27,8 @@ class SiteIndex(SearchMixin):
choice_header = 'DCIM'
@register_search(Rack)
class RackIndex(SearchMixin):
model = Rack
queryset = Rack.objects.prefetch_related('site', 'location', 'tenant', 'tenant__group', 'role').annotate(
device_count=count_related(Device, 'rack')
)
@ -37,8 +38,8 @@ class RackIndex(SearchMixin):
choice_header = 'DCIM'
@register_search(RackReservation)
class RackReservationIndex(SearchMixin):
model = RackReservation
queryset = RackReservation.objects.prefetch_related('rack', 'user')
filterset = dcim.filtersets.RackReservationFilterSet
table = dcim.tables.RackReservationTable
@ -46,8 +47,8 @@ class RackReservationIndex(SearchMixin):
choice_header = 'DCIM'
@register_search(Location)
class LocationIndex(SearchMixin):
model = Site
queryset = Location.objects.add_related_count(
Location.objects.add_related_count(Location.objects.all(), Device, 'location', 'device_count', cumulative=True),
Rack,
@ -61,8 +62,8 @@ class LocationIndex(SearchMixin):
choice_header = 'DCIM'
@register_search(DeviceType)
class DeviceTypeIndex(SearchMixin):
model = DeviceType
queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(
instance_count=count_related(Device, 'device_type')
)
@ -72,8 +73,8 @@ class DeviceTypeIndex(SearchMixin):
choice_header = 'DCIM'
@register_search(Device)
class DeviceIndex(SearchMixin):
model = Device
queryset = Device.objects.prefetch_related(
'device_type__manufacturer',
'device_role',
@ -90,8 +91,8 @@ class DeviceIndex(SearchMixin):
choice_header = 'DCIM'
@register_search(ModuleType)
class ModuleTypeIndex(SearchMixin):
model = ModuleType
queryset = ModuleType.objects.prefetch_related('manufacturer').annotate(
instance_count=count_related(Module, 'module_type')
)
@ -101,8 +102,8 @@ class ModuleTypeIndex(SearchMixin):
choice_header = 'DCIM'
@register_search(Module)
class ModuleIndex(SearchMixin):
model = Module
queryset = Module.objects.prefetch_related(
'module_type__manufacturer',
'device',
@ -114,8 +115,8 @@ class ModuleIndex(SearchMixin):
choice_header = 'DCIM'
@register_search(VirtualChassis)
class VirtualChassisIndex(SearchMixin):
model = VirtualChassis
queryset = VirtualChassis.objects.prefetch_related('master').annotate(
member_count=count_related(Device, 'virtual_chassis')
)
@ -125,8 +126,8 @@ class VirtualChassisIndex(SearchMixin):
choice_header = 'DCIM'
@register_search(Cable)
class CableIndex(SearchMixin):
model = Cable
queryset = Cable.objects.all()
filterset = dcim.filtersets.CableFilterSet
table = dcim.tables.CableTable
@ -134,25 +135,10 @@ class CableIndex(SearchMixin):
choice_header = 'DCIM'
@register_search(PowerFeed)
class PowerFeedIndex(SearchMixin):
model = PowerFeed
queryset = PowerFeed.objects.all()
filterset = dcim.filtersets.PowerFeedFilterSet
table = dcim.tables.PowerFeedTable
url = 'dcim:powerfeed_list'
choice_header = 'DCIM'
DCIM_SEARCH_TYPES = {
'site': SiteIndex,
'rack': RackIndex,
'rackreservation': RackReservationIndex,
'location': LocationIndex,
'devicetype': DeviceTypeIndex,
'device': DeviceIndex,
'moduletype': ModuleTypeIndex,
'module': ModuleIndex,
'virtualchassis': VirtualChassisIndex,
'cable': CableIndex,
'powerfeed': PowerFeedIndex,
}

View File

@ -5,5 +5,4 @@ class ExtrasConfig(AppConfig):
name = "extras"
def ready(self):
import extras.lookups
import extras.signals
from . import lookups, search, signals

View File

@ -29,4 +29,5 @@ registry['model_features'] = {
feature: collections.defaultdict(set) for feature in EXTRAS_FEATURES
}
registry['denormalized_fields'] = collections.defaultdict(list)
registry['search'] = collections.defaultdict(dict)
registry['views'] = collections.defaultdict(dict)

View File

@ -6,4 +6,4 @@ class IPAMConfig(AppConfig):
verbose_name = "IPAM"
def ready(self):
import ipam.signals
from . import signals, search

View File

@ -1,13 +1,12 @@
import ipam.filtersets
import ipam.tables
from django.db import models
from ipam.models import ASN, VLAN, VRF, Aggregate, IPAddress, Prefix, Service
from netbox.search.models import SearchMixin
from utilities.utils import count_related
from netbox.search import register_search
@register_search(VRF)
class VRFIndex(SearchMixin):
model = VRF
queryset = VRF.objects.prefetch_related('tenant', 'tenant__group')
filterset = ipam.filtersets.VRFFilterSet
table = ipam.tables.VRFTable
@ -15,8 +14,8 @@ class VRFIndex(SearchMixin):
choice_header = 'IPAM'
@register_search(Aggregate)
class AggregateIndex(SearchMixin):
model = Aggregate
queryset = Aggregate.objects.prefetch_related('rir')
filterset = ipam.filtersets.AggregateFilterSet
table = ipam.tables.AggregateTable
@ -24,8 +23,8 @@ class AggregateIndex(SearchMixin):
choice_header = 'IPAM'
@register_search(Prefix)
class PrefixIndex(SearchMixin):
model = Prefix
queryset = Prefix.objects.prefetch_related(
'site', 'vrf__tenant', 'tenant', 'tenant__group', 'vlan', 'role'
)
@ -35,8 +34,8 @@ class PrefixIndex(SearchMixin):
choice_header = 'IPAM'
@register_search(IPAddress)
class IPAddressIndex(SearchMixin):
model = IPAddress
queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant', 'tenant__group')
filterset = ipam.filtersets.IPAddressFilterSet
table = ipam.tables.IPAddressTable
@ -44,8 +43,8 @@ class IPAddressIndex(SearchMixin):
choice_header = 'IPAM'
@register_search(VLAN)
class VLANIndex(SearchMixin):
model = VLAN
queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'tenant__group', 'role')
filterset = ipam.filtersets.VLANFilterSet
table = ipam.tables.VLANTable
@ -53,8 +52,8 @@ class VLANIndex(SearchMixin):
choice_header = 'IPAM'
@register_search(ASN)
class ASNIndex(SearchMixin):
model = ASN
queryset = ASN.objects.prefetch_related('rir', 'tenant', 'tenant__group')
filterset = ipam.filtersets.ASNFilterSet
table = ipam.tables.ASNTable
@ -62,21 +61,10 @@ class ASNIndex(SearchMixin):
choice_header = 'IPAM'
@register_search(Service)
class ServiceIndex(SearchMixin):
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'
IPAM_SEARCH_TYPES = {
'vrf': VRFIndex,
'aggregate': AggregateIndex,
'prefix': PrefixIndex,
'ipaddress': IPAddressIndex,
'vlan': VLANIndex,
'asn': ASNIndex,
'service': ServiceIndex,
}

View File

@ -0,0 +1 @@
from .register import register_search

View File

@ -4,6 +4,8 @@ from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.db.models.signals import post_save, pre_delete
from django.urls import reverse
from extras.registry import registry
from netbox.constants import SEARCH_MAX_RESULTS
# The cache for the initialized backend.
@ -71,7 +73,12 @@ class SearchBackend(object):
pre_delete.connect(self._pre_delete_receiver, model)
def get_registry(self):
return self._registered_models
# return self._registered_models
r = {}
for app_label, models in registry['search'].items():
r.update(**models)
return r
# Signalling hooks.

View File

@ -1,30 +0,0 @@
from circuits.search_indexes import CIRCUIT_SEARCH_TYPES
from dcim.search_indexes import DCIM_SEARCH_TYPES
from extras.search_indexes import JOURNAL_SEARCH_TYPES
from ipam.search_indexes import IPAM_SEARCH_TYPES
from tenancy.search_indexes import TENANCY_SEARCH_TYPES
from virtualization.search_indexes import VIRTUALIZATION_SEARCH_TYPES
from wireless.search_indexes import WIRELESS_SEARCH_TYPES
SEARCH_TYPE_HIERARCHY = {
'Circuits': CIRCUIT_SEARCH_TYPES,
'DCIM': DCIM_SEARCH_TYPES,
'IPAM': IPAM_SEARCH_TYPES,
'Tenancy': TENANCY_SEARCH_TYPES,
'Virtualization': VIRTUALIZATION_SEARCH_TYPES,
'Wireless': WIRELESS_SEARCH_TYPES,
'Journal': JOURNAL_SEARCH_TYPES,
}
def build_search_types():
result = dict()
for app_types in SEARCH_TYPE_HIERARCHY.values():
for name, items in app_types.items():
result[name] = items
return result
SEARCH_TYPES = build_search_types()

View File

@ -6,8 +6,8 @@ from django.apps import apps
from django.conf import settings
from django.utils.module_loading import module_has_submodule
from extras.registry import registry
from .backends import default_search_engine
from .hierarchy import SEARCH_TYPES
def get_app_modules():
@ -19,8 +19,13 @@ def get_app_modules():
def register():
for name, module in SEARCH_TYPES.items():
default_search_engine.register(name, module)
# for name, module in SEARCH_TYPES.items():
# default_search_engine.register(name, module)
for app_label, models in registry['search'].items():
for name, cls in models.items():
default_search_engine.register(name, cls)
for name, module in get_app_modules():
submodule_name = "search_indexes"
@ -37,3 +42,15 @@ def register():
cls_name = cls_obj.model.__name__.lower()
if not default_search_engine.is_registered(cls_name, cls_obj):
default_search_engine.register(cls_name, cls_obj)
def register_search(model):
def _wrapper(cls):
app_label = model._meta.app_label
model_name = model._meta.model_name
registry['search'][app_label][model_name] = cls
return cls
return _wrapper

View File

@ -3,3 +3,6 @@ from django.apps import AppConfig
class TenancyConfig(AppConfig):
name = 'tenancy'
def ready(self):
from . import search

View File

@ -1,13 +1,13 @@
import tenancy.filtersets
import tenancy.tables
from django.db import models
from netbox.search.models import SearchMixin
from netbox.search import register_search
from tenancy.models import Contact, ContactAssignment, Tenant
from utilities.utils import count_related
@register_search(Tenant)
class TenantIndex(SearchMixin):
model = Tenant
queryset = Tenant.objects.prefetch_related('group')
filterset = tenancy.filtersets.TenantFilterSet
table = tenancy.tables.TenantTable
@ -15,8 +15,8 @@ class TenantIndex(SearchMixin):
choice_header = 'Tenancy'
@register_search(Contact)
class ContactIndex(SearchMixin):
model = Contact
queryset = Contact.objects.prefetch_related('group', 'assignments').annotate(
assignment_count=count_related(ContactAssignment, 'contact')
)
@ -24,9 +24,3 @@ class ContactIndex(SearchMixin):
table = tenancy.tables.ContactTable
url = 'tenancy:contact_list'
choice_header = 'Tenancy'
TENANCY_SEARCH_TYPES = {
'tenant': TenantIndex,
'contact': ContactIndex,
}

View File

@ -3,3 +3,6 @@ from django.apps import AppConfig
class VirtualizationConfig(AppConfig):
name = 'virtualization'
def ready(self):
from . import search

View File

@ -1,13 +1,14 @@
import virtualization.filtersets
import virtualization.tables
from django.db import models
from dcim.models import Device
from netbox.search.models import SearchMixin
from netbox.search import register_search
from utilities.utils import count_related
from virtualization.models import Cluster, Device, VirtualMachine
from virtualization.models import Cluster, VirtualMachine
@register_search(Cluster)
class ClusterIndex(SearchMixin):
model = Cluster
queryset = Cluster.objects.prefetch_related('type', 'group').annotate(
device_count=count_related(Device, 'cluster'), vm_count=count_related(VirtualMachine, 'cluster')
)
@ -17,8 +18,8 @@ class ClusterIndex(SearchMixin):
choice_header = 'Virtualization'
@register_search(VirtualMachine)
class VirtualMachineIndex(SearchMixin):
model = VirtualMachine
queryset = VirtualMachine.objects.prefetch_related(
'cluster',
'tenant',
@ -31,9 +32,3 @@ class VirtualMachineIndex(SearchMixin):
table = virtualization.tables.VirtualMachineTable
url = 'virtualization:virtualmachine_list'
choice_header = 'Virtualization'
VIRTUALIZATION_SEARCH_TYPES = {
'cluster': ClusterIndex,
'virtualmachine': VirtualMachineIndex,
}

View File

@ -5,4 +5,4 @@ class WirelessConfig(AppConfig):
name = 'wireless'
def ready(self):
import wireless.signals
from . import signals, search

View File

@ -1,14 +1,14 @@
import wireless.filtersets
import wireless.tables
from dcim.models import Interface
from django.db import models
from netbox.search.models import SearchMixin
from netbox.search import register_search
from utilities.utils import count_related
from wireless.models import WirelessLAN, WirelessLink
@register_search(WirelessLAN)
class WirelessLANIndex(SearchMixin):
model = WirelessLAN
queryset = WirelessLAN.objects.prefetch_related('group', 'vlan').annotate(
interface_count=count_related(Interface, 'wireless_lans')
)
@ -18,16 +18,10 @@ class WirelessLANIndex(SearchMixin):
choice_header = 'Wireless'
@register_search(WirelessLink)
class WirelessLinkIndex(SearchMixin):
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'
WIRELESS_SEARCH_TYPES = {
'wirelesslan': WirelessLANIndex,
'wirelesslink': WirelessLinkIndex,
}