Skip to content

search

django_spire.core.search

__all__ = ['Search', 'SearchResult', 'get_search_registry'] module-attribute

SearchResult dataclass

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

action = SearchCommand.Action.OPEN_URL_CURRENT_TAB class-attribute instance-attribute

Source code in django_spire/core/search/result.py
@classmethod
def from_search(cls, search: Search, obj: models.Model) -> SearchResult:
    url = search.generate_detail_url(obj)

    if url is None:
        message = f'{search.__class__.__name__} does not have a detail url for search results.'
        raise ValueError(message)

    return cls(
        name=search.section_name,
        icon=search.icon,
        label=search.result_name(obj),
        description=search.result_description(obj),
        url=url,
    )

from_command classmethod

Source code in django_spire/core/search/result.py
@classmethod
def from_command(cls, search: Search, command: SearchCommand) -> SearchResult:
    return cls(
        name=search.section_name,
        icon=command.icon,
        label=command.name,
        description=command.description,
        url=command.url,
        action=command.action,
    )

from_list classmethod

Source code in django_spire/core/search/result.py
@classmethod
def from_list(cls, search: Search, url: str) -> SearchResult:
    return cls(
        name=search.section_name,
        icon='bi-list-columns',
        label=search.section_name,
        description='List Page',
        url=url,
    )

generate_tag_attributes

Source code in django_spire/core/search/result.py
def generate_tag_attributes(self) -> str:
    if self.action == SearchCommand.Action.OPEN_URL_CURRENT_TAB:
        return f'href="{self.url}"'
    elif self.action == SearchCommand.Action.OPEN_URL_NEW_TAB:
        return f'href="{self.url}" target="_blank"'
    elif self.action == SearchCommand.Action.DISPATCH_MODAL:
        return f'href="#" @click="Spire.modal.dispatchView(\'{self.url}\')"'
    else:
        return f'href="{self.url}"'

Search

Bases: ABC

Command = SearchCommand class-attribute instance-attribute

model_class = None class-attribute instance-attribute

searchable_fields = None class-attribute instance-attribute

searchable_commands = [] class-attribute instance-attribute

name instance-attribute

icon instance-attribute

permission_required = 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 = 'name', 'icon'

    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)

base_queryset abstractmethod

Source code in django_spire/core/search/search.py
@abstractmethod
def base_queryset(self, request: HttpRequest) -> models.QuerySet:
    raise NotImplementedError

generate_list_url abstractmethod

Source code in django_spire/core/search/search.py
@abstractmethod
def generate_list_url(self) -> str | None:
    raise NotImplementedError

generate_detail_url abstractmethod

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

result_description abstractmethod

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

result_name abstractmethod

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

search

Source code in django_spire/core/search/search.py
def search(self, request: HttpRequest, query_string: str | None) -> models.QuerySet | None:
    if self.searchable_fields is None:
        return 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(request)

    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)

commands_for_query

Source code in django_spire/core/search/search.py
def commands_for_query(self, query_string: str) -> list[SearchCommand]:
    query = (query_string or '').strip().lower()

    if not query:
        return []

    words = query.split(' ')

    return [
        command
        for command in self.searchable_commands
        if all(word in command.name.lower() for word in words)
    ]

list_result

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

    if not query:
        return None

    if self.model_class is not None:
        keywords = (
            self.name,
            self.model_class._meta.verbose_name,
            self.model_class._meta.verbose_name_plural,
        )
    else:
        keywords = (self.name,)

    if not any(keyword and query in keyword.lower() for keyword in keywords):
        return None

    list_url = self.generate_list_url()

    if list_url is None:
        return None

    return SearchResult.from_list(self, list_url)

command_result

Source code in django_spire/core/search/search.py
def command_result(self, command: SearchCommand) -> SearchResult:
    return SearchResult.from_command(self, command)

get_search_registry

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

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

    return search_registry