From c31d746494f4c1f6851e17cb724890b0a9bb0f1c Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 27 Sep 2022 10:33:34 -0700 Subject: [PATCH] 8927 refactor search --- netbox/netbox/forms/__init__.py | 36 ++++++++++--------------- netbox/netbox/settings.py | 2 +- netbox/search/backends.py | 19 +++++++++++++ netbox/utilities/templatetags/search.py | 9 +++++-- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/netbox/netbox/forms/__init__.py b/netbox/netbox/forms/__init__.py index 4ea4f1fe2..0b7933adf 100644 --- a/netbox/netbox/forms/__init__.py +++ b/netbox/netbox/forms/__init__.py @@ -6,27 +6,10 @@ from search.backends import default_search_engine from .base import * -def build_search_choices(): - result = list() - result.append(('', 'All Objects')) - for category, items in default_search_engine.get_registry().items(): - subcategories = list() - for slug, obj in items.items(): - name = obj.queryset.model._meta.verbose_name_plural - name = name[0].upper() + name[1:] - subcategories.append((slug, name)) - result.append((category, tuple(subcategories))) +def build_options(choices): + options = [{"label": choices[0][1], "items": []}] - return tuple(result) - - -OBJ_TYPE_CHOICES = build_search_choices() - - -def build_options(): - options = [{"label": OBJ_TYPE_CHOICES[0][1], "items": []}] - - for label, choices in OBJ_TYPE_CHOICES[1:]: + for label, choices in choices[1:]: items = [] for value, choice_label in choices: @@ -38,5 +21,14 @@ def build_options(): class SearchForm(BootstrapMixin, forms.Form): q = forms.CharField(label='Search') - obj_type = forms.ChoiceField(choices=OBJ_TYPE_CHOICES, required=False, label='Type') - options = build_options() + options = None + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields["obj_type"] = forms.ChoiceField(choices=default_search_engine.get_search_choices(), required=False, label='Type') + + def get_options(self): + if not self.options: + self.options = build_options(default_search_engine.get_search_choices()) + + return self.options diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index d61e5cac9..dc3f90d04 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -319,6 +319,7 @@ INSTALLED_APPS = [ 'social_django', 'taggit', 'timezone_field', + 'search', 'circuits', 'dcim', 'ipam', @@ -330,7 +331,6 @@ INSTALLED_APPS = [ 'wireless', 'django_rq', # Must come after extras to allow overriding management commands 'drf_yasg', - 'search', ] # Middleware diff --git a/netbox/search/backends.py b/netbox/search/backends.py index 61bb80b8a..69fb50979 100644 --- a/netbox/search/backends.py +++ b/netbox/search/backends.py @@ -20,6 +20,7 @@ class SearchBackend(object): """A search engine capable of performing multi-table searches.""" _created_engines: dict = dict() + _search_choices = tuple() @classmethod def get_created_engines(cls): @@ -66,6 +67,24 @@ class SearchBackend(object): # Signalling hooks. + def get_search_choices(self): + if self._search_choices: + return self._search_choices + + result = list() + result.append(('', 'All Objects')) + for category, items in self.get_registry().items(): + subcategories = list() + for slug, obj in items.items(): + name = obj.queryset.model._meta.verbose_name_plural + name = name[0].upper() + name[1:] + subcategories.append((slug, name)) + result.append((category, tuple(subcategories))) + + self._search_choices = tuple(result) + print(self._search_choices) + return self._search_choices + def _use_hooks(self): raise NotImplementedError diff --git a/netbox/utilities/templatetags/search.py b/netbox/utilities/templatetags/search.py index 5726ae5d5..c9cd04380 100644 --- a/netbox/utilities/templatetags/search.py +++ b/netbox/utilities/templatetags/search.py @@ -4,13 +4,18 @@ from django import template register = template.Library() -search_form = SearchForm() +search_form = None @register.inclusion_tag("search/searchbar.html") def search_options(request) -> Dict: + global search_form + + if not search_form: + search_form = SearchForm() + """Provide search options to template.""" return { - 'options': search_form.options, + 'options': search_form.get_options(), 'request': request, }