API Reference

modelsearch.backends.get_search_backend(backend='default', **kwargs)

Get the search backend instance for the given backend name. This name can be:

  • An identifier for a backend as defined in MODELSEARCH_BACKENDS

  • A dotted path to a backend class, in the form "modelsearch.backends.elasticsearch" or "modelsearch.backends.elasticsearch.ElasticsearchSearchBackend". If a path to a module is given, get_search_backend will attempt to find a SearchBackend class within that module.

If no name is specified, default will be used; this defaults to the modelsearch.backends.database backend if not specified in MODELSEARCH_BACKENDS.

All options within the MODELSEARCH_BACKENDS entry (except for BACKEND itself) will be passed to the backend class during instantiation. Additional keyword arguments will also be passed to the backend class (and override options from MODELSEARCH_BACKENDS).

class modelsearch.backends.base.BaseSearchBackend(params)

The base class for all search backends.

A backend is the entry point for all search and indexing functionality. Any request to index an object for searching or to perform a search query will be directed at a backend.

The searching and indexing functionality is delegated to various helper classes, which are specified as attributes on the backend class.

Helper classes

query_compiler_class = None

The BaseSearchQueryCompiler subclass responsible for compiling whole-word search queries.

autocomplete_query_compiler_class = None

The BaseSearchQueryCompiler subclass responsible for compiling autocomplete (partial word) search queries.

index_class = <class 'modelsearch.backends.base.BaseIndex'>

The BaseIndex subclass responsible for managing the indexes for this backend.

results_class = None

The BaseSearchResults subclass responsible for representing search results.

rebuilder_class = None

The class responsible for rebuilding indexes for this backend. Can be None if the backend does not require index rebuilding. This class will be instantiated once for each distinct index returned by get_index_for_model across all indexed models. No base class is provided. Instead, this should be a class with the following interface:

  • __init__(self, index): Initializes the rebuilder with the given index.

  • start(self): Performs any initialization required to start the rebuild process, and returns the index.

  • finish(self): Performs any finalization required to finish the rebuild process.

Index management

catch_indexing_errors = False

Whether indexing errors should be caught and logged, rather than raised. Catching these errors is appropriate for backends that use an external service such as Elasticsearch, where an interruption in service should not bring down the whole application.

get_index_for_model(model)

Returns the index to be used for the given model. The base implementation returns an instance of self.index_class instantiated with no parameters other than the backend itself, which is appropriate for backends that manage a single index. Backends that manage multiple indexes should override this method to return the appropriate index for the model.

get_index_for_object(obj)

Returns the index to be used for the given model instance. This is a convenience wrapper around get_index_for_model.

all_indexes()

Returns a sequence of all indexes used by this backend.

refresh_indexes()

Refreshes all indexes used by this backend. This performs any housekeeping required by the index so that recently-updated data is visible to searches. Not all backends require this - for the ones that don’t, this is a null operation.

reset_indexes()

Resets all indexes used by this backend. This deletes all data from the indexes.

Indexing operations

add(obj)

Adds a single object to the data store managed by this backend.

add_bulk(model, obj_list)

Adds multiple objects of the same model to the data store managed by this backend.

delete(obj)

Deletes a single object from the data store managed by this backend.

Searching

search(query, model_or_queryset, fields=None, operator=None, order_by_relevance=True)

Performs a whole-word search.

Parameters:
  • query – The search query string.

  • model_or_queryset – The model class or queryset to search within.

  • fields – An optional list of field names to restrict the search to.

  • operator – The operator to use when combining search terms ("and" or "or").

  • order_by_relevance – Whether to order results by relevance.

autocomplete(query, model_or_queryset, fields=None, operator=None, order_by_relevance=True)

Performs an autocomplete (partial word match) search.

Parameters:
  • query – The search query string.

  • model_or_queryset – The model class or queryset to search within.

  • fields – An optional list of field names to restrict the search to.

  • operator – The operator to use when combining search terms ("and" or "or").

  • order_by_relevance – Whether to order results by relevance.

Internal method that handles both search() and autocomplete() queries, by receiving the appropriate query compiler class to use. This performs the following steps:

  • Normalises the model_or_queryset parameter into a queryset, using model.objects.all() if a model class is provided.

  • Short-circuits the query compiler if the model is not indexed, the query is an empty string, or the fields list is empty, returning an empty result set in these cases.

  • Instantiates the query compiler with the queryset, query string, and any additional keyword arguments.

  • Calls check() on the query compiler to validate the query.

  • Returns a results_class instance, passing in the backend and the query compiler.

Parameters:
  • query_compiler_class – The BaseSearchQueryCompiler subclass to use for compiling the query.

  • query – The search query string.

  • model_or_queryset – The model class or queryset to search within.

  • kwargs – Additional keyword arguments as passed to search() or autocomplete(), to pass on to the query compiler.

class modelsearch.backends.base.BaseIndex(backend)

The base class for all indexes.

An index manages the storage for some subset of objects in the backend’s data store. A backend can work with either a single index (as the database backends do) - in which case get_index_for_model and get_index_for_object will always return the same Index instance - or multiple indexes (as with the Elasticsearch backend, which operates a separate index for each base model).

Partitioning objects across indexes by any criteria other than model is not currently supported - that is, the backend’s get_index_for_object method must always return a result that corresponds to get_index_for_model for that object’s type.

On the base class, all methods are null operations. This can be used directly for backends that do not need to maintain their own data store (such as the fallback database backend, which queries the database directly).

get_key()

Returns a hashable value that uniquely identifies this index within the search backend.

add_model(model)

Performs any configuration required for this index to accept documents of the given model.

refresh()

Performs any housekeeping required by the index so that recently-updated data is visible to searches.

reset()

Resets the index to its initial state, deleting all data.

add_item(obj)

Adds a single object to the index.

add_items(model, items)

Adds multiple objects of the same model to the index.

delete_item(item)

Deletes a single object from the index.

class modelsearch.backends.base.BaseSearchResults(backend, query_compiler, prefetch_related=None)

Represents the results of a search query. This emulates a Django QuerySet, but with the results not necessarily coming from the database - the result set can be sliced to obtain a new SearchResults instance, and the search is only actually performed when the results are iterated or evaluated as a list, or when the count() method is called.

The process for performing a search is specific to each backend, and involves some division of work between the search results class and the query compiler.

To be implemented by subclasses - performs the actual search query, returning an iterable sequence of results.

_do_count()

To be implemented by subclasses - returns the result count.

class modelsearch.backends.base.BaseSearchQueryCompiler(queryset, query, fields=None, operator=None, order_by_relevance=True)

Represents a search query translated into an expression that the search backend can understand, incorporating the necessary filters, ordering, and other query parameters originating from either the search query or the queryset. No actual querying happens at the point of instantiating this; that happens when the associated BaseSearchResults object is evaluated.

HANDLES_ORDER_BY_EXPRESSIONS = False

Whether this query compiler can handle complex expressions in the order_by clause of the queryset, such as F("title").asc(nulls_first=True). If true, the check() method will not raise an exception when such expressions are encountered.

check()

Checks that the search query satisfies the following conditions:

  1. All field names passed in the fields parameter exist as SearchField records on the model.

  2. All fields used within filters on the passed queryset exist as FilterField records on the model.

  3. The order_by clause on the passed queryset does not contain any expressions other than plain field names and their reversed counterparts ("some_field" and "-some_field"), unless HANDLES_ORDER_BY_EXPRESSIONS is True.

  4. All field names within the order_by clause on the passed queryset exist as FilterField records on the model.

_get_filters_from_queryset(check_only=False)

Internal method used by check() to validate that all fields specified as filters on the queryset exist as FilterField records on the model, and that all lookup clauses (such as __lt) are recognised. Backends may also use this to translate the filter clause into an alternative data structure for use during searching.

Parameters:

check_only – If True, the method will simply return None if no invalid filters are found. If False, the _process_lookup, _process_match_none and _connect_filters methods must be overridden; this method will then return the translated data structure obtained by applying these methods to the queryset’s filter clause.

_get_filters_from_where_node(where_node, check_only=False)

Internal method used by _get_filters_from_queryset to recursively validate a sub-expression of the queryset’s filter clause.

Parameters:

check_only – If True, the method will simply return None if where_node and all sub-expressions within it are valid. If False, the _process_lookup, _process_match_none and _connect_filters methods must be overridden; this method will then return the translated data structure obtained by applying these methods to where_node.

_get_order_by()

Internal method used by check() to validate that all fields specified in the queryset’s order_by clause exist as FilterField records on the model. Backends may also use this to construct the query to send to the underlying search mechanism.

Returns an iterable sequence of (reverse, field) tuples where reverse is a boolean indicating whether ordering on that field is reversed, and field is the FilterField instance. If HANDLES_ORDER_BY_EXPRESSIONS is True, complex expressions within the order_by clause are skipped over; if False, they raise an OrderByFieldError.

_process_lookup(field_path, lookup, value)

To be implemented by subclasses if they wish to call _get_filters_from_queryset with check_only=False. Returns the data structure corresponding to a filter lookup on an individual field.

Parameters:

field_path – The list of search_fields definitions leading to the FilterField instance

for the field being filtered on, consisting of zero or more RelatedFields definitions followed by the FilterField. :param lookup: The identifier for the type of lookup being performed, such as "exact" or "lt". :param value: The lookup value.

_process_match_none()

To be implemented by subclasses if they wish to call _get_filters_from_queryset with check_only=False. Returns the data structure corresponding to a lookup that returns an empty result set.

_connect_filters(filters, connector, negated)

To be implemented by subclasses if they wish to call _get_filters_from_queryset with check_only=False. Returns the data structure corresponding to the combination of multiple filters.

Parameters:
  • filters – The data structures for the sub-expressions to be combined.

  • connector – The clause used to connect the filters - "AND" or "OR".

  • negated – Whether the final expression should be negated.