Clean up search view form

This commit is contained in:
jeremystretch 2022-10-17 16:00:54 -04:00
parent e66902c05c
commit bcc5f6c504
5 changed files with 35 additions and 42 deletions

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from netbox.search.backends import search_backend from netbox.search.backends import search_backend
from utilities.forms import BootstrapMixin from utilities.forms import BootstrapMixin, StaticSelectMultiple
from .base import * from .base import *
@ -21,18 +21,21 @@ def build_options(choices):
class SearchForm(BootstrapMixin, forms.Form): class SearchForm(BootstrapMixin, forms.Form):
q = forms.CharField(label='Search') q = forms.CharField(label='Search')
obj_types = forms.MultipleChoiceField(
choices=[],
required=False,
label='Object type(s)',
widget=StaticSelectMultiple()
)
options = None options = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields["obj_type"] = forms.ChoiceField(
choices=search_backend.get_search_choices(), self.fields['obj_types'].choices = search_backend.get_object_types()
required=False,
label='Type'
)
def get_options(self): def get_options(self):
if not self.options: if not self.options:
self.options = build_options(search_backend.get_search_choices()) self.options = build_options(search_backend.get_object_types())
return self.options return self.options

View File

@ -12,6 +12,7 @@ from extras.models import CachedValue
from extras.registry import registry from extras.registry import registry
from netbox.constants import SEARCH_MAX_RESULTS from netbox.constants import SEARCH_MAX_RESULTS
from utilities.querysets import RestrictedPrefetch from utilities.querysets import RestrictedPrefetch
from utilities.templatetags.builtins.filters import bettertitle
from . import FieldTypes, LookupTypes, SearchResult, get_registry from . import FieldTypes, LookupTypes, SearchResult, get_registry
# The cache for the initialized backend. # The cache for the initialized backend.
@ -42,7 +43,7 @@ class SearchBackend:
post_save.connect(self.caching_handler) post_save.connect(self.caching_handler)
post_delete.connect(self.removal_handler) post_delete.connect(self.removal_handler)
def get_search_choices(self): def get_object_types(self):
"""Return the set of choices for individual object types, organized by category.""" """Return the set of choices for individual object types, organized by category."""
if not self._search_choice_options: if not self._search_choice_options:
@ -50,7 +51,7 @@ class SearchBackend:
categories = defaultdict(dict) categories = defaultdict(dict)
for app_label, models in registry['search'].items(): for app_label, models in registry['search'].items():
for name, cls in models.items(): for name, cls in models.items():
title = cls.model._meta.verbose_name.title() title = bettertitle(cls.model._meta.verbose_name)
value = f'{app_label}.{name}' value = f'{app_label}.{name}'
categories[cls.get_category()][value] = title categories[cls.get_category()][value] = title

View File

@ -150,18 +150,18 @@ class HomeView(View):
class SearchView(View): class SearchView(View):
def get(self, request): def get(self, request):
form = SearchForm(request.GET)
object_types = None
results = [] results = []
# Initialize search form
form = SearchForm(request.GET) if 'q' in request.GET else SearchForm()
if form.is_valid(): if form.is_valid():
# Restrict results by object type # Restrict results by object type
if form.cleaned_data['obj_type']: object_types = []
app_label, model_name = form.cleaned_data['obj_type'].split('.') for obj_type in form.cleaned_data['obj_types']:
object_types = [ app_label, model_name = obj_type.split('.')
ContentType.objects.get_by_natural_key(app_label, model_name) object_types.append(ContentType.objects.get_by_natural_key(app_label, model_name))
]
results = search_backend.search(request, form.cleaned_data['q'], object_types=object_types) results = search_backend.search(request, form.cleaned_data['q'], object_types=object_types)

View File

@ -16,10 +16,21 @@
{% endblock tabs %} {% endblock tabs %}
{% block content-wrapper %} {% block content-wrapper %}
<div class="tab-content"> <div class="row px-3">
<div class="col col-6 offset-3 py-3">
<form action="{% url 'search' %}" method="get" class="form form-horizontal">
{% render_form form %}
<div class="text-end">
<button type="submit" class="btn btn-primary">
<span class="mdi mdi-magnify" aria-hidden="true"></span> Search
</button>
</div>
</form>
</div>
</div>
{% if request.GET.q %} {% if request.GET.q %}
{% if results %} {% if results %}
<div class="row"> <div class="row px-3">
<div class="col"> <div class="col">
<div class="card"> <div class="card">
<div class="card-body table-responsive"> <div class="card-body table-responsive">
@ -32,7 +43,7 @@
</tr> </tr>
{% for result in results %} {% for result in results %}
<tr> <tr>
<td>{{ result.object|content_type }}</td> <td>{{ result.object|meta:"verbose_name"|bettertitle }}</td>
<td> <td>
<a href="{{ result.object.get_absolute_url }}">{{ result.object }}</a> <a href="{{ result.object.get_absolute_url }}">{{ result.object }}</a>
</td> </td>
@ -48,26 +59,5 @@
{% else %} {% else %}
<h3 class="text-muted text-center">No results found</h3> <h3 class="text-muted text-center">No results found</h3>
{% endif %} {% endif %}
{% else %}
<div class="row">
<div class="col col-12 col-lg-6 offset-lg-3">
<form action="{% url 'search' %}" method="get" class="form form-horizontal">
<div class="card">
<h5 class="card-header">
Search
</h5>
<div class="card-body">
{% render_form form %}
</div>
<div class="card-footer text-end">
<button type="submit" class="btn btn-primary">
<span class="mdi mdi-magnify" aria-hidden="true"></span> Search
</button>
</div>
</div>
</form>
</div>
</div>
{% endif %} {% endif %}
</div>
{% endblock content-wrapper %} {% endblock content-wrapper %}

View File

@ -5,10 +5,9 @@
aria-label="Search" aria-label="Search"
placeholder="Search" placeholder="Search"
class="form-control" class="form-control"
value="{{ request.GET.q|escape }}"
/> />
<input name="obj_type" hidden type="text" class="search-obj-type" /> <input name="obj_types" hidden type="text" class="search-obj-type" />
<span class="input-group-text search-obj-selected">All Objects</span> <span class="input-group-text search-obj-selected">All Objects</span>