mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-24 08:25:17 -06:00
Utilize global registry to register model search classes
This commit is contained in:
parent
5797ba0fd7
commit
e67965ae22
@ -6,4 +6,4 @@ class CircuitsConfig(AppConfig):
|
||||
verbose_name = "Circuits"
|
||||
|
||||
def ready(self):
|
||||
import circuits.signals
|
||||
from . import signals, search
|
||||
|
@ -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,
|
||||
}
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
@ -5,5 +5,4 @@ class ExtrasConfig(AppConfig):
|
||||
name = "extras"
|
||||
|
||||
def ready(self):
|
||||
import extras.lookups
|
||||
import extras.signals
|
||||
from . import lookups, search, signals
|
||||
|
@ -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)
|
||||
|
@ -6,4 +6,4 @@ class IPAMConfig(AppConfig):
|
||||
verbose_name = "IPAM"
|
||||
|
||||
def ready(self):
|
||||
import ipam.signals
|
||||
from . import signals, search
|
||||
|
@ -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,
|
||||
}
|
@ -0,0 +1 @@
|
||||
from .register import register_search
|
@ -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.
|
||||
|
||||
|
@ -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()
|
@ -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
|
||||
|
@ -3,3 +3,6 @@ from django.apps import AppConfig
|
||||
|
||||
class TenancyConfig(AppConfig):
|
||||
name = 'tenancy'
|
||||
|
||||
def ready(self):
|
||||
from . import search
|
||||
|
@ -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,
|
||||
}
|
@ -3,3 +3,6 @@ from django.apps import AppConfig
|
||||
|
||||
class VirtualizationConfig(AppConfig):
|
||||
name = 'virtualization'
|
||||
|
||||
def ready(self):
|
||||
from . import search
|
||||
|
@ -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,
|
||||
}
|
@ -5,4 +5,4 @@ class WirelessConfig(AppConfig):
|
||||
name = 'wireless'
|
||||
|
||||
def ready(self):
|
||||
import wireless.signals
|
||||
from . import signals, search
|
||||
|
@ -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,
|
||||
}
|
Loading…
Reference in New Issue
Block a user