Skip to content

search

django_spire.core.search

__all__ = ['BaseSearch', 'SearchResult', 'get_search_class', 'get_search_registry'] module-attribute

SearchResult dataclass

search_key instance-attribute

name instance-attribute

icon = None class-attribute instance-attribute

label = '' class-attribute instance-attribute

description = None class-attribute instance-attribute

url = '' class-attribute instance-attribute

Source code in django_spire/core/search/result.py
@classmethod
def from_search(cls, search: BaseSearch, obj: models.Model) -> SearchResult:
    return cls(
        search_key=search.search_key,
        name=search.section_name,
        icon=search.icon,
        label=search.result_name(obj),
        description=search.result_description(obj),
        url=search.generate_url(obj),
    )

BaseSearch

Bases: ABC

model_class instance-attribute

searchable_fields instance-attribute

search_key instance-attribute

name = None class-attribute instance-attribute

icon = None class-attribute instance-attribute

permission = None class-attribute instance-attribute

result_limit = 10 class-attribute instance-attribute

section_name property

__init_subclass__

Source code in django_spire/core/search/search.py
def __init_subclass__(cls, **kwargs) -> None:
    super().__init_subclass__(**kwargs)

    required_attributes = 'model_class', 'searchable_fields', 'search_key'

    for attribute in required_attributes:
        if getattr(cls, attribute, None) is None:
            message = f'{cls.__name__}.{attribute} is None and must be defined'
            raise ValueError(message)

generate_url abstractmethod

Source code in django_spire/core/search/search.py
@abstractmethod
def generate_url(self, obj: models.Model) -> str:
    raise NotImplementedError

result_description

Source code in django_spire/core/search/search.py
def result_description(self, obj: models.Model) -> str | None:  # noqa: ARG002
    return None

result_name

Source code in django_spire/core/search/search.py
def result_name(self, obj: models.Model) -> str:
    return str(obj)

base_queryset

Source code in django_spire/core/search/search.py
def base_queryset(self) -> models.QuerySet:
    manager = self.model_class.objects

    if hasattr(manager, 'not_deleted'):
        return manager.not_deleted()

    return manager.all()

search

Source code in django_spire/core/search/search.py
def search(self, query_string: str | None) -> models.QuerySet | None:
    query_string = (query_string or '').strip()

    if not query_string:
        return None

    if not self.searchable_fields:
        return self.model_class.objects.none()

    words = query_string.split(' ')

    queryset = self.base_queryset()

    for word in words:
        conditions = models.Q()

        for field in self.searchable_fields:
            conditions |= models.Q(**{f'{field}__icontains': word})

        queryset = queryset.filter(conditions)

    return queryset[: self.result_limit]

to_result

Source code in django_spire/core/search/search.py
def to_result(self, obj: models.Model) -> SearchResult:
    return SearchResult.from_search(self, obj)

get_search_class

Source code in django_spire/core/search/registry.py
def get_search_class(search_key: str) -> type[BaseSearch] | None:
    module_string = settings.DJANGO_SPIRE_SEARCH_REGISTRY.get(search_key)

    if module_string is None:
        return None

    return _resolve_search_class(search_key, module_string)

get_search_registry

Source code in django_spire/core/search/registry.py
def get_search_registry() -> dict[str, type[BaseSearch]]:
    search_registry: dict[str, type[BaseSearch]] = {}

    for search_key, module_string in settings.DJANGO_SPIRE_SEARCH_REGISTRY.items():
        search_registry[search_key] = _resolve_search_class(search_key, module_string)

    return search_registry