You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
psrGROUP/env/Lib/site-packages/haystack/backends/simple_backend.py

134 lines
3.8 KiB

"""
A very basic, ORM-based backend for simple search during tests.
"""
from functools import reduce
from warnings import warn
from django.db.models import Q
from haystack import connections
from haystack.backends import (
BaseEngine,
BaseSearchBackend,
BaseSearchQuery,
SearchNode,
log_query,
)
from haystack.inputs import PythonData
from haystack.models import SearchResult
from haystack.utils import get_model_ct_tuple
class SimpleSearchBackend(BaseSearchBackend):
def update(self, indexer, iterable, commit=True):
warn("update is not implemented in this backend")
def remove(self, obj, commit=True):
warn("remove is not implemented in this backend")
def clear(self, models=None, commit=True):
warn("clear is not implemented in this backend")
@log_query
def search(self, query_string, **kwargs):
hits = 0
results = []
result_class = SearchResult
models = (
connections[self.connection_alias].get_unified_index().get_indexed_models()
)
if kwargs.get("result_class"):
result_class = kwargs["result_class"]
if kwargs.get("models"):
models = kwargs["models"]
if query_string:
for model in models:
if query_string == "*":
qs = model.objects.all()
else:
for term in query_string.split():
queries = []
for field in model._meta.fields:
if hasattr(field, "related"):
continue
if field.get_internal_type() not in (
"TextField",
"CharField",
"SlugField",
):
continue
queries.append(Q(**{"%s__icontains" % field.name: term}))
if queries:
qs = model.objects.filter(
reduce(lambda x, y: x | y, queries)
)
else:
qs = []
hits += len(qs)
for match in qs:
match.__dict__.pop("score", None)
app_label, model_name = get_model_ct_tuple(match)
result = result_class(
app_label, model_name, match.pk, 0, **match.__dict__
)
# For efficiency.
result._model = match.__class__
result._object = match
results.append(result)
return {"results": results, "hits": hits}
def prep_value(self, db_field, value):
return value
def more_like_this(
self,
model_instance,
additional_query_string=None,
start_offset=0,
end_offset=None,
limit_to_registered_models=None,
result_class=None,
**kwargs
):
return {"results": [], "hits": 0}
class SimpleSearchQuery(BaseSearchQuery):
def build_query(self):
if not self.query_filter:
return "*"
return self._build_sub_query(self.query_filter)
def _build_sub_query(self, search_node):
term_list = []
for child in search_node.children:
if isinstance(child, SearchNode):
term_list.append(self._build_sub_query(child))
else:
value = child[1]
if not hasattr(value, "input_type_name"):
value = PythonData(value)
term_list.append(value.prepare(self))
return (" ").join(map(str, term_list))
class SimpleEngine(BaseEngine):
backend = SimpleSearchBackend
query = SimpleSearchQuery