Extend search() to accept a lookup type

This commit is contained in:
jeremystretch 2022-10-12 15:12:26 -04:00
parent 14858dd790
commit 7f86cffff6
2 changed files with 17 additions and 8 deletions

View File

@ -8,12 +8,18 @@ ObjectFieldValue = namedtuple('ObjectFieldValue', ('name', 'type', 'weight', 'va
class FieldTypes: class FieldTypes:
BOOLEAN = 'bool'
FLOAT = 'float' FLOAT = 'float'
INTEGER = 'int' INTEGER = 'int'
STRING = 'str' STRING = 'str'
class LookupTypes:
EXACT = 'iexact'
PARTIAL = 'icontains'
STARTSWITH = 'istartswith'
ENDSWITH = 'iendswith'
class SearchIndex: class SearchIndex:
""" """
Base class for building search indexes. Base class for building search indexes.
@ -36,8 +42,6 @@ class SearchIndex:
@staticmethod @staticmethod
def get_field_type(instance, field_name): def get_field_type(instance, field_name):
field_cls = instance._meta.get_field(field_name).__class__ field_cls = instance._meta.get_field(field_name).__class__
if issubclass(field_cls, models.BooleanField):
return FieldTypes.BOOLEAN
if issubclass(field_cls, (models.FloatField, models.DecimalField)): if issubclass(field_cls, (models.FloatField, models.DecimalField)):
return FieldTypes.FLOAT return FieldTypes.FLOAT
if issubclass(field_cls, models.IntegerField): if issubclass(field_cls, models.IntegerField):

View File

@ -11,11 +11,13 @@ from django.db.models.signals import post_delete, post_save
from extras.models import CachedValue 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 . import SearchResult from . import FieldTypes, LookupTypes, SearchResult
# The cache for the initialized backend. # The cache for the initialized backend.
_backends_cache = {} _backends_cache = {}
DEFAULT_LOOKUP_TYPE = LookupTypes.PARTIAL
def get_indexer(model): def get_indexer(model):
app_label = model._meta.app_label app_label = model._meta.app_label
@ -67,7 +69,7 @@ class SearchBackend:
return self._search_choice_options return self._search_choice_options
def search(self, request, value, **kwargs): def search(self, request, value, lookup=DEFAULT_LOOKUP_TYPE):
""" """
Search cached object representations for the given value. Search cached object representations for the given value.
""" """
@ -113,7 +115,7 @@ class FilterSetSearchBackend(SearchBackend):
Legacy search backend. Performs a discrete database query for each registered object type, using the FilterSet Legacy search backend. Performs a discrete database query for each registered object type, using the FilterSet
class specified by the index for each. class specified by the index for each.
""" """
def search(self, request, value, **kwargs): def search(self, request, value, lookup=DEFAULT_LOOKUP_TYPE):
results = [] results = []
search_registry = self.get_registry() search_registry = self.get_registry()
@ -153,12 +155,15 @@ class FilterSetSearchBackend(SearchBackend):
class CachedValueSearchBackend(SearchBackend): class CachedValueSearchBackend(SearchBackend):
def search(self, request, value, **kwargs): def search(self, request, value, lookup=DEFAULT_LOOKUP_TYPE):
# Define the search parameters # Define the search parameters
params = { params = {
'value__icontains': value f'value__{lookup}': value
} }
if lookup != LookupTypes.EXACT:
# Partial matches are valid only on string values
params['type'] = FieldTypes.STRING
# Construct the base queryset to retrieve matching results # Construct the base queryset to retrieve matching results
queryset = CachedValue.objects.filter(**params).annotate( queryset = CachedValue.objects.filter(**params).annotate(